In Object Oriented programming (i.e. the Java programming language) Inheritance is one of the key principles that is beneficial to use in the design of any software application. Java inheritance allows for a neat way to define relationships between your Objects (and in turn re-use your code so you don't have to type the same stuff over and over again).

What is Java Inheritance

So what do I mean when I say that Inheritance allows you to define relationships between Objects? Well, let's think of some examples of Objects that DO have one or more relationships. Think the object Vehicle, this is a fairly generic term for:

  1. Car
  2. Bus
  3. Motorcycle

Do you see how a Car is a Vehicle, how a Bus is a Vehicle, how a Motorcycle is a Vehicle etc. This is a relationship is what Java Inheritance is all about. When you can verbally say that something is a something else, then you have a relationship between those two Objects, and therefore you have Inheritance.

How does Inheritance help us?

Well, with the examples given above, this means that a Car inherits behaviours and/or attributes from a Vehicle. So let's think about this for a second, what is a Car? Well, it's a Vehicle with four wheels, doors and around 5 seats. Okay, what's a Bus? It's also a Vehicle likely with more than 4 wheels, doors and probably somewhere around 30 seats. What's a Motorcycle? It's a Vehicle with two wheels, no doors and one or two seats. Once you start to “map” out all of the characteristics of your Objects, you'll begin to see what similarities they have (i.e. what they have in relation), and also what they don't have in relation to each other. This is very important with Java inheritance. If all your Objects share something in common, then this can be considered an attribute of the super class. Whatever they do not have in common will be attributes of the child classes.

What is a super Class and what is a child Class?

With our example, the super class is the Vehicle object and the child classes are the Car, Bus and Motorcycle. The super Class is essentially the Object that will hold all the attributes that are common. So our Vehicle super Class would have the following attributes:

  • Wheels
  • Seats

From our inspection of all the types of Vehicles above, we identify that all types of Vehicles have wheels and seats. But notice that I didn't put doors as part of the Vehicle object. This is because Motorcycles don't have doors! Doors would only be attributes of Cars and Busses, so we will have a door attribute on the Car and Bus Objects. Make sense?

Coding Inheritance in Java

When we're coding this thing called Inheritance in Java, what does it look like? Well it can take the form of either an Interface or an Abstract Class. I'll talk more about what these are specifically in a later post, but for now all you need to know about them is this:

  • Interface = An outline (or skeleton) of an Object with no implementation
  • Abstract Class = An outline of an Object that can contain an implementation

Without further delay, let's look at some examples of an Interface and an abstract class.

Interface

public interface Vehicle
{
  public Integer getNumberOfSeats();
  public Integer getNumberOfWheels();
  public String getVehicleType();
}

Here we've declared an Interface for our Vehicle and it has three methods, getNumberOfSeats(), getNumberOfWheels() and getVehicleType(). As you can see, there is no implementation of the code, we've just outlined some methods. So, now to make this interface useful, we need to implement it somewhere! So let's see what that would look like:

public class Car implements Vehicle
{
  @Override
  public Integer getNumberOfSeats()
  {
    return 5;
  }

  @Override
  public Integer getNumberOfWheels()
  {
    return 4;
  }

  @Override
  public String getVehicleType()
  {
    return "Car";
  }

  public Integer getNumberOfDoors()
  {
    return 2;
  }
}

This is what the Car‘s implementation of the Vehicle interface would look like! For this example, I've stated (in code) that a Car has 5 seats, 4 wheels and 2 doors. Let's see what a Bus would look like:

public class Bus implements Vehicle
{

  @Override
  public Integer getNumberOfSeats()
  {
    return 35;
  }

  @Override
  public Integer getNumberOfWheels()
  {
    return 6;
  }

  @Override
  public String getVehicleType()
  {
    return "Bus";
  }

  public Integer getNumberOfDoors()
  {
    return 4;
  }
}

Pretty self explanatory right? Well, except for those @Override lines. What do those mean? These are called annotations and these were introduced in Java version 5 (we are currently on Java version 7). An annotation is anything that you see with an @ (at) symbol before some text above a method declaration or a class declaration. These particular @Override annotations are just saying that the method below it are from a parent (or super) class, and we are implementing the desired behaviour in this particular class. In the case of an Interface, we have to override the methods, as it's a requirement with Interfaces.

Take special note that we don't have an @Override annotation on our getNumberOfDoors() method. This is because it wasn't declared in our Interface. Remember why? Because a Motorcycle doesn't have doors, so it wouldn't make sense to put it in the Interface! Now, don't get me wrong, in the world of programming there are always several ways to solve the same problem, so you could have put something like hasDoors() in the Vehicle Interface and had it return a Boolean value of true or false (true in the case of Car and Bus, false in the case of Motorcycle). But, for the purpose of illustrating that you can have your own non-overridden methods in your child classes, I chose to do it the way I did it.

Abstract Class

So how about we look at abstract classes now. Remember that abstract classes don't necessarily need their methods overridden, and the methods can contain implementation if you want. If we were to create an abstract class for the Vehicle object, it could look like this:

public abstract class Vehicle
{
  public String vehicleType;

  public Integer getNumberOfSeats()
  {
    if (this.vehicleType.equals("Car"))
    {
      return 5;
    }
    else if (this.vehicleType.equals("Bus"))
    {
      return 20;
    }
    else if (this.vehicleType.equals("Motorcycle"))
    {
      return 1;
    }

    // the vehicleType variable has not yet been set to anything,
    // so we cannot say what number of seats this vehicle has, so
    // we will return null.
    return null;
  }

  public String getVehicleType()
  {
    return this.vehicleType;
  }

  public abstract Integer getNumberOfWheels();
}

So as you can see here, we have some real code implemented in our getNumberOfSeats() method. The code relies on the vehicleType attribute. So let's take a look at how a child class would use this Vehicle abstract class:

public class Car extends Vehicle
{
  public Car ()
  {
    this.vehicleType = "Car";
  }

  public Integer getNumberOfWheels()
  {
    return 4;
  }
}

The first noticeable difference between an interface and an abstract class, is that you need to use the keyword implements when you want a child class to use an Interface and you need to use the keyword extends when you want a child class to use an abstract class. We've also done something interesting with this code:

  public Car ()
  {
    this.vehicleType = "Car";
  }

This is called a constructor. The purpose of a constructor in Java is to outline a section of code that will be executed when an Object is first instantiated. So, this just means that when someone creates an instance of our Car Object, Java will automatically set the vehicleType to be “Car”. I'll post a video that shows the code flow of constructors in Java, so no worries if this doesn't make sense right away.

So now, if we were to write some code get the number of seats that our Car has, we would see that it has 5, because Java will see that the super class (Vehicle) has a method that defines the number of seats (getNumberOfSeats()).

Okay, so now for those who want to go the extra mile, I challenge you to put together a Java program that will allow you to use an abstract Vehicle class and properly output the following console lines:

My Car has 2 seats.
My Car has 4 wheels.
My Bus has 20 seats.
My Bus has 6 wheels.

Using this Java main class:

  public static void main(String[] args)
  {
    Vehicle myCar = new Car();
    System.out.println("My " + myCar.getVehicleType() + " has " + myCar.getNumberOfSeats() + " seats.");
    System.out.println("My " + myCar.getVehicleType() + " has " + myCar.getNumberOfWheels() + " wheels.");

    Vehicle myBus = new Bus();
    System.out.println("My " + myBus.getVehicleType() + " has " + myBus.getNumberOfSeats() + " seats.");
    System.out.println("My " + myBus.getVehicleType() + " has " + myBus.getNumberOfWheels() + " wheels.");
  }

Try your best and if you get stuck, just leave a comment on this post and I'll see what I can do to help you out! Remember, the best way to learn is to practice, practice, practice! So running into problems is a good thing, you just need to make sure you don't get frustrated an give up, so please ask me for help before you give up! Also, if you want more help with learning Java to become a full-stack developer, learn more about our Online Full Stack Developer Bootcamp here.

 

Free Java Beginners Course

Start learning how to code today with our free beginners course. Learn more.