Inheritance is one of the most powerful concepts in all of programming. Without it, it’d be tough to do many of the cool things we do. One of my favorite games as a kid was Conquer 2.0. The game was fun because you could be anything, and at the same time, each thing was like the others. Yes different and the same at the same time. Isn’t that wonderful? Let me explain. In Conquer, you can be an Archer, Monk, Ninja, Warrior, or one of two types of a Taoist. The great thing about the game is that no one class is much different from another and if you want to be another class, it isn’t too hard to understand how it works. This is possible because every class is built upon a single class, and, consequently, they all share similar attributes and functionalities. There is no Human class in Conquer, but it is clear that all of the classes mentioned above are humans with distinctive super powers. An Archer can fly and shoot fire arrows, a Ninja can run fast and attack with stars, a Warrior can wield a sword and a sword, and a Taoist can perform magical acts and heal others. While those classes appear different, they are more alike than you may think. Every class extends the capability of a Human. A Human can jump, attack, and heal itself. Further, every human has a name, health, attack power, and experience. All of that adds up to two attributes and five functions. That’s essentially all it takes to create a game like Conquer. Where it gets fun is when we create the different classes with unique attributes and functionalities while still inheriting all the attributes and functionalities universal to all humans from the Human class. This is where subclassing and inheritance come in. Why Inheritance is Important & Useful By default, all classes in Java inherit from the Object class provided by Java. Therefore, the Object class is the to all other classes and it defines methods that all its share. While the Object class only defines the methods its subclasses share, superclasses can define fields their subclasses share as well. This is important because it allows us to have the vital relationship between objects. Even more important is the ability to write parts of our class definition once and share it with other classes that are similar in some ways. This is great for keeping our code DRY (Don’t Repeat Yourself) and encapsulating shared functionalities of our classes in their superclasses. superclass subclasses is-a In our Conquer game, if we know that all classes can jump, attack, and heal as well as have a name, health, attack power, and experience, we can put all of that in a superclass called Human. With a Human superclass, we will only need to add the unique parts of each subclass to the class itself. This will allow us to write less code as well as build a predictable interface for users of our game. Subclassing & Inheritance To have a superclass is to , or inherit from, a class. Thus, to be a subclass is to extend a class. Every class in Java can have only one direct superclass from which it inherits some of its fields and methods. However, a class that has a superclass can also be inherited from as to create a chain of inheritance; this is known as class hierarchy. extend From its superclass, a class inherits all fields and methods that are not declared as . This creates a contract between the subclass, its superclass, and the user of the classes. With the contract, the user can expect the behavior of the superclass to be present in its subclasses. However, the contract only goes one way. Fields and methods declared in a subclass are not available in the superclass unless they are declared there, too. private Extending a class is easy in Java. All you have to do is choose a class to extend and write the keyword “extends” followed by the name of the class to extend at the end of your class declaration but before the opening closing brace: Human {_//add fields and methods_} public class Archer Human {_//inherits fields and methods of its Human superclass//add more fields and methods for this class_} public class extends In that code snippet, we have a Human class which, in theory, has fields and methods. We also have a Archer class which, also in theory, has its own fields and methods and extends our Human class to inherit its fields and methods. Let’s add some fields and methods to our Human class to see how the Archer can inherit them: Human { String ; = 100.0; = 0; = 1; public class protected name protected double health protected long experience protected int attackPower **public** Human(String name) { **this**.**name** \= name; gainExperience(1); } **public long** gainExperience(**long** experience){ **this**.**experience** += experience; **return** experience; } **public long** addAttackPower(**long** attackPower) { **this**.**attackPower** += attackPower; **return** attackPower; } **public double** heal(**double** additionalHealth) { **health** += additionalHealth; **return health**; } **public void** attack(Human opponent) { opponent.decreaseHealth(**attackPower**); } **private void** decreaseHealth(**int** attackPower) { **health** \-= attackPower; } **public void** jump() { System.**_out_**.println(**"Jumped up"**); } ... } Now, instances of every subclass of our Human class will be able to attack other Human instances, be attacked, heal, jump, gain experience, and increase their attack power. Notice that I said that instances of every subclass of our human class will be able to attack Human instances. I say this because every instance of a class is also an instance of the class’s superclass. other The instance method of our Human class takes a Human opponent as a parameter and drains its health. This is great because we only need to write one attack method that will work on all instances of our Human class regardless of the instance being an Archer, Monk, Wizard, or any other class that extends our Human class. This is at work and we will learn more about it later. Simply put, polymorphism is the idea that we can group many different classes together as being one class, such as saying all archers, monks, and wizards are also humans. They all pass more than one test. Without inheritance, we would have to write a different attack method for each class we may come in contact with. That would be awful. attack() polymorphism is-a Method Overriding All classes that extend our Human class will share the same attack method. That means that every subclass of our Human class will attack the same way as the other subclasses of our Human class. This wouldn’t be such a good design because a user is expecting a Warrior to attack with a sword and an Archer to attack with a bow and arrow. Method overriding in Java allows us to accomplish such a design. A subclass can the methods of its superclass to implement its own behavior if it is necessary. Method overriding allows a subclass to decide how to implement behavior expected by the user through the inheritance contract. In our game, a user will expect that all classes can attack other classes, but they also expect that each class attacks in a unique way. Therefore, each subclass of our Human class should override the instance method to implement its own attack behavior. This is easy in Java. All we have to do to override a method from a superclass is to add the annotation above the method in the subclass: override attack() @Override FireArcher Archer { = 1;... public class extends int firePower @Override **public void** attack(Human opponent) { System.**_out_**.println(**"**Attacking **"** \+ opponent.getName() + **"** with fire arrows!**"**); opponent.decreaseHealth(**attackPower** \+ **firePower**); } } Warrior Human {... public class extends @Override **public void** attack(Human opponent) { System.**_out_**.println(**"**Attacking **"** \+ opponent.getName() \+ **"** with my sword!**"**); **super**.attack(opponent); } } Monk Human {...} public class extends Notice that the FireArcher class extends the Archer class which extends the Human class. This is an example of a class hierarchy from bottom to top: FireArcher → Archer → Human. In that code snippet, we have a FireArcher, Warrior, and Monk class. All three classes extend the Human class and inherit its fields and methods, but only the FireArcher and the Warrior class override the instance method of the Human class. The Monk class doesn’t do anything special when it attacks, so it is fine with the basic Human attack() method. attack() When we override methods of the superclass, we can choose to invoke the superclass’s implementation of that method by accessing the super class through the keyword provided by Java and calling the method on it at any point in the method. We do this at the end of the overridden method in the Warrior class but not in the FireArcher class because a FireArcher deals damage to opponents differently than most other classes; with its fire, a FireArcher deals additional damage to an opponent’s health. super attack() Finally, because an instance of a class is also an instance of its superclass, a subclass must implement at least one of the constructor methods that are declared in its superclass and/or invoke the implementation of one of its superclass’s constructors by accessing the super class through the keyword: super Archer Human { = 0; public class extends private int numArrows //1. this constructor works **public** Archer(String name) { **super**(name); findArrows(); } //2. this constructor works **public** Archer(String name, int startingArrows) { **this.name = name;** numArrows = startingArrows; } **private void** findArrows() { System.**_out_**.println(**"Looking for arrows"**); } } We must call the superclass’s constructor at the start in of the subclass’s constructor in at least one of the subclass’s constructors. In the second constructor, we don’t have to call the superclass’s constructor because it is called in the first constructor. There are many other rules surrounding the constructors of a superclass and its subclasses, but this is enough to get you started. Try to see how you can break the contract and you will quickly learn the other rules. Finally, notice that we accessed and set the instance field in the Archer class’s second constructor although it is not declared directly in the Archer class. This is only possible because that field, as we learned earlier, is inherited from the Human superclass. name We can now create instances of all our classes — Human, Archer, Warrior, and FireArcher — and expect them to share methods and fields while behaving distinctively: Main { main(String[] args){Human human = Human( );Human archer = Archer( );FireArcher fireArcher = FireArcher( );Warrior warrior = Warrior( ); public class public static void new "Lisa" new "Samuel" new "Emmanuel" new "Carolyn" human.attack(fireArcher); archer.attack(warrior); warrior.attack(archer); fireArcher.attack(human); } } Abstract Class & Interfaces We have learned a good deal about class inheritance, but there’s a little more to learn before we are masters of inheritance and polymorphism. Soon, we will learn how to make better class contracts with abstract classes and interface classes. Next Chapter _In the Class Inheritance chapter, we learned about forming a contract between classes, superclasses, and users._medium.com Java for Humans {Abstract Classes & Interfaces} Table of Contents _I am writing this book to teach anybody with the slightest bit of interest in computer science, software engineering…_medium.com Java for Humans {Table of Contents}