Zach Cochran
by Zach Cochran
5 min read

Categories

Tags

Coming off of the talk of constructors and variables, we’re going to move on to the concept of inheritance.

This is a topic that completely baffled me back when I took coding classes in school… of course that’s not really saying much as most of the classes had left me completely confused, but I digress. Inheritance isn’t that hard at all and it actually provides a huge amount of functionality to your code by using it. This is why it’s one of the main pillars of OOP.

What Is Inheritance?

Inheritance allows you to essentially build classes off of one another. You start with a base class and then continue to extend that functionality on with additional classes. Each of these new classes are denoting with an extends modifier in their declaration, pointing back to the base class in which they’re expanding.

Each class is able to extend from exactly one class (you can’t stick a bunch of them in there). But that’s not to say that you can’t chain more than once! As we’ll see in an example below, there’s nothing preventing you from chaining multiple classes together.

The interesting thing to note here is that even if your class doesn’t explicitly extend another class, it will automagically extend the Object class. This won’t be visible in your code, but it will be there. How can you tell? Well, the Object class comes with its own set of methods that are available to use right out of the box. Create a new class. Then try to call the .toString() method. Surprise! You didn’t write it, but it’s available for you to use!

And that’s what inheritance is all about. As you continue to extend classes, you keep the abilities of the base class, but add more functionality on top of it. That means that any constructors, methods, or properties that existed in the base class will be available to use in the extended class.

Inheritance Example

Let’s start working through an example of this to get a better idea of what’s going on. I’m going to create a base class called Animal which really has nothing more than a few properties and some getters and setters:

package inheritance.animals;

public class Animal {
   private int legs;
   private String sound;
   private String species;

   public Animal() {

   }

   public String makeSound() {
       return "The " + getSpecies() + " goes " + getSound();
   }

   public int getLegs() {
       return legs;
   }

   public void setLegs(int legs) {
       this.legs = legs;
   }

   public String getSound() {
       return sound;
   }

   public void setSound(String sound) {
       this.sound = sound;
   }

   public String getSpecies() {
       return species;
   }

   public void setSpecies(String species) {
       this.species = species;
   }
}

This is just a normal class. Nothing special going on here.

But now let’s say that I wanted to extend Animal to support a Dog class. I could add in a few more parameters and maybe add few constructors:

public class Dog extends Animal {
   private String breed;

   public Dog() {
       setSpecies("K9");
       setLegs(4);
       setSound("Woof!");
   }

   public Dog(String breed) {
       this();
       this.breed = breed;
   }

   public String getBreed() {
       return breed;
   }

   public void setBreed(String breed) {
       this.breed = breed;
   }
}

Notice how the declaration says Dog extends Animal. This is what will give us access to everything inside of the Animal class. This means that we can call methods inside the Animal class, like our setters and getters, just by calling their method name. See how we’re setting our values in dog?

Super and Override

By default, when you extend from a class you will be implicitly calling the empty constructor of the base class. Anything that’s set in that base class is going to be set when you initialize your new extended class.

But what if you want to specify a different constructor than the default empty set? That’s where super comes in.

With super you can actually specify specifically what you want to pass up to the base class constructor, allowing for different constructors to be hit. Let’s take a look a another super simple example:

public class Shiba extends Dog {
   public Shiba() {
       super("Shiba-Inu");
   }
}

In this case I’m just declaring another class and extending from Dog this time (notice how this is the second extension of Animal). Everything from the Animal and Dog classes (as well as Object) are available to us.

Because I am making an object for an explicit type of dog, I already know what it’s breed is. Therefor I want to utilize the constructor that accepts the breed back in the Dog class. To do so, I call super("Shiba-Inu").

But what if you need to modify some of the functionality of one of methods from a base class? That’s where the @Override annotation comes in! You can preface your method declaration with an @Override to allow for the functionality of that method to now be overridden with your new class.

Example time. Remember that in our initial declaration of the Animal class, we had created a method called makeSound(). Now that we know exactly what kind of breed of dog we’re talking about, we know exactly what sound it’s going to make. So let’s override that method with a new one for our Shiba:

public class Shiba extends Dog {
   public Shiba() {
       super("Shiba-Inu");
   }

   @Override
   public String makeSound() {
      return "The Shiba-Inu goes REEEEEE!";
   }
}

It’s that easy!

…but what if you still want to access the original makeSound() in another method? super is back again to help us out!

public class Shiba extends Dog {
   public Shiba() {
       super("Shiba-Inu");
   }

   @Override
   public String makeSound() {
      return "The Shiba-Inu goes REEEEEE!";
   }

   public String originalSound() {
       return super.makeSound();
   }
}

By using super.makeSound() we gain access back to the method even though we’re overriding it in this same class!

Wrap Up

Hopefully you found some of this helpful or interesting. There’s still some more topics that I need to cover with regards to inheritance that I hope to cover in tomorrow’s blog.

As always, the code from this post can be found over in my github repo.

💚 A.B.L.