Inheritance in Java Complete Tutorial

In this section we will learn what the Inheritance is and how to use it in Java.

What is inheritance in Java?

Car companies usually have multiple models of cars for sale. But if you closely look at some of these models in a company, you’ll see that some of these cars have the same body structure but with just different engine or different interior design, etc.

Or you might see some of these cars have the same engine but use different body structure!

What happens in car companies is that, in the day one, they designed a unique car (unique body, engine, gearbox etc.) And years later, when they’ve got enough budget to produce another model, they use some of the old blueprints that they used for the first model to create the second one. This is because they realized the second model in a few areas is in common with the old one. (For example the same structure but different engine!). So instead of just repeating themselves by creating exactly the same blueprint (map) for the body of the second model (god knows how much money and time could be wasted here), they simply use the one that is already there!

This is what inheritance means! If you think about it, in this car company, the second model is inheriting its body structure from another car!

In the world of Java programming, we have the same concept for the same purpose (save time and money).

It happens many times that we create a class in a program that its members can be used for other classes and so instead of copying members in each class, a class can inherit from another one and use its members.

This way, only in one place we create class members and if in the future, there was need to modify the body of a class, the modification will be only in one class.

Related terminology to inheritance in Java

When it comes to inheritance, there are a few terminologies that you need to know about because you’ll hear about them not just in this series of tutorials but also in other resources as well.

– Java Super class (Base class| Parent class):

A class that other classes inherit from is called a superclass or base class or even a parent class.

– Java Subclass (Child class):

A class that inherits from another class is called the subclass or child class.

– Java Reusability:

The word `reusability` in the world of Java means reusing codes and classes so that we don’t have to recreate the same source code in other places. This way, if in the future we needed to modify the target code, the change will only happen in one place. Basically, this way we don’t need to modify the same source code in multiple different places.

What Does Extends Mean in Java?

In order for a class to inherit from another class, we use the keyword `extends` after the name of the child class (the class that want to inherit from another class) and after that we use the name of the class that want this child class to inherit from.

Java extends Keyword Syntax:

class ChildClass extends ParentClass{/*…*/}

The `extends` keyword comes after the name of the child class and before the name of the parent class (or base class).

Inheritance Example in Java:

Create a class named `Employee` and put the code below into that class:

public class Employee {
    private String name;
    private String lastName;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
}

 

Now create another class named `Manager` and put the code below into that file:

public class Manager extends Employee{

}

Here we’ve used the keyword `extends` after the name of the class and after that we’ve used the name of the class from which we want to inherit members from.

Now create a class named `Simple` and put the code below into that file:

public class Simple {
    public static void main(String[] args) {
        Manager manager = new Manager();
        manager.setName("Jack");
        manager.setLastName("Doe");
        System.out.println(manager.getName());
        System.out.println(manager.getLastName());
    }
}

Output:

Jack

Doe

How does inheritance work in Java?

In this example, as you can see, the body of the `Manager` class is empty but still an object of this class is able to work with methods declared inside the parent class which is `Employee`.

Notes:

  • The class that uses the members of another class is called `child class` as well as `sub class`. So in the example above, the `Manager` class is the child or sub-class.
  • The class that let others to use its members is called `base class` as well as `parent class`. So the `Employee` in this example is the base or parent class.
  • Members of the base class should be either `public` or `protected` so the sub-class be able to access them. (`private` members are not accessible from sub-classes).
  • When we create an object from a subclass, all the member variables of the child and the ancestor classes (all the classes in the chain of inheritance that are above the sub-class(check the note below)) will be instantiated.

The instantiation happens from top to bottom. In the example above, the compiler first checks the members of the `Employee` class to see what variable it can find to instantiate and then it moves to the `Manager` class and looks for variables to instantiate them as well.

Note: actually instantiation happens from a class named Object.(we explained this in its section)

  • When an object of a child class calls a method, first the body of the child class is checked to see if this method is defined here. If it couldn’t find such a method, it will check the body of the parent class. If in the parent class there wasn’t any definition of such method, then runtime engine will look through all the ancestors (chain of classes that the child class inherited from) to see which one has this method. Finally, if it couldn’t find such a method, we will get runtime error.

This is an important topic, and we covered it in the inheritance and constructors section.

Example: Inheritance in Java

Keep all three classes of the first example and create another class named `PartTimeEmployee` and put the code below into that class:

public class PartTimeEmployee extends Employee {

    public void jobDescription(){
        System.out.println("Hi, I'm a part time employee :)");
    }
}

As you can see, just like the `Manager` class, the `PartTimeEmployee` also inherited from the `Employee` class as well. So now the `Employee` class is the parent of both `PartTimeEmployee` and the `Manager` class.

This `PartTimeEmployee` class has one method on its own which is `jobDescription()`.

Alright, let’s refactor the `Simple` class and change the body of the `main` method like this:

public class Simple {
    public static void main(String[] args) {
        PartTimeEmployee pte = new PartTimeEmployee();
        pte.setName("John");
        pte.setLastName("Doe");
        System.out.println(pte.getName());
        System.out.println(pte.getLastName());
        pte.jobDescription();
    }
}

Output:

John

Doe

Hi, I'm a part-time employee 🙂

In this example, we’ve created an object from the `PartTimeEmployee` class and stored the memory address of the object to the `pte` variable. So now the `pte` variable is pointing to this object.

When we called the `setName()` and `setLastName()` methods via `pte` variable, the runtime checked the members of the `PartTimeEmployee` class to see if these methods are defined here. Because these methods are not defined in this class, the runtime will check the parent class `Employee` to see if these methods are defined there. Of course, these methods are set in the `Employee` class and so the runtime will use the definition of the methods in that class and use those to execute the instructions.

Basically, the runtime will go through the chain of classes one at a time starting from the child-class itself until either find the target member or it’ll return error (in case didn’t find the target member in any ancestor classes).

For example, the ` jobDescription()` method is defined in the `PartTimeEmployee` class itself, so the runtime will directly use this method in the child class instead of moving up to other parent classes.

Java Types of inheritance:

In Java, inheritance has different models. Let’s see what these models are:

1- Single inheritance in Java

A single inheritance means a child class inherits from a base class and that’s it. Basically, in a single inheritance model, there are only two classes involve and one of them is a child class, and the other is the base class or the parent class if you will.

The last example you’ve seen was an example of a single inheritance in Java.

2- Multilevel inheritance in Java

A parent class can itself be the child of another class! For example, if we have 3 classes named A, B and C, then A can be the parent of the B and the class B can be the parent of the class C. In this case the class B is the parent of the C as well as the sub-class of the A.

Example:

class A{..}

class B extends A{…}

class C extends B{…}

In such case, the class B has the access to all the non-private members of the class A. Also the class C has the access to non-private members of the class B as well as class A. This means a child class is linked to a chain of classes and the non-private members of all the ancestor classes (those above the child class) are accessible in the child class.

3- Inheritance Hierarchy in Java

In Java, multiple different classes can inherit from one class. This is known as a hierarchical inheritance in Java.

Example:

class A{..}

class B extends A{…}

class C extends A{…}

class D extends A{…}

As you can see, the class A is the parent of the classes `B`, `C`, and `D`.

4- Multiple Inheritance in Java

Multiple inheritance means one class inherits from two or more classes!

In Java we can’t extend a class to two or more classes using the extends keyword!

For example:

class A extends B, C{/*...*/}

This will return error.

But a class can inherit from two or more interfaces! Please check the Java interface section to learn more about this topic.

Final Classes and Inheritance

In the Java final section, we’ve mentioned that a class that is set to final can’t be inherited from! If we do so, we will get a compile time error!

Let’s see this in practice now:

Example: inheriting from a final class in Java

First, create a class named Animal with this body and make sure the class is set to final:

package com.example.demo;

public final class Animal {
    public void saySomething(){
        System.out.println("The animal is making noise...");
    }
}

Now create another class named Cat and extend it to the Animal, like the example below:

package com.example.demo;

public class Cat extends Animal {
}

Now in the Main class, create an instance of the Cat class and run the program:

package com.example.demo;

public class Main {

    public static void main(String[] args) {
        Cat cat = new Cat();
    }
}

Output:

Error: java: cannot inherit from final com.example.demo.Animal

As you can see, we got error because we’ve tried to make the Cat class to inherit from the Animal class.

Note: Change the package names if you’re using a different package.

Java inheritance and protected members

In a parent class, those members that have the access specifiers set to protect, the child class can access them directly.

But remember, as mentioned in the Java access specifier section, a protected member is only accessible within the body of the child classes but they are not accessible using the instance objects that are created from either the parent class or the child class!

Example: protected members and inheritance in Java

package com.example.demo;

public class Animal {
    protected void saySomething(){
        System.out.println("The animal is making noise...");
    }
}


package com.example.demo;

public class Cat extends Animal {
    public void makeNoise(){
        saySomething();
    }
}


package com.example.demo;

public class Main {

    public static void main(String[] args) {
        Cat cat = new Cat();
        cat.makeNoise();
    }
}

Output:

The animal is making noise…

In this example, the Animal class has a protected method called `saySomething()`. This means the method is only accessible within the body of the Animal class as well as all the child classes. But other than these areas, we can’t access this method.

For example, if we attempt to call this method using the instance that was created from the `Cat` object, we would’ve got a compile time error.

More to Read:

Java inheritance and method overriding

Java inheritance and super keyword

 

Facebook
Twitter
Pinterest
LinkedIn

Top Technologies