Inheritance in Java


JavaViews 2634

Inheritance in Java is one of the most important features of an Object-oriented programming system(OOPs). We have seen an overview of inheritance in the previous tutorial of OOPs concepts in Java. In this tutorial, we will understand in detail about inheritance in java and its type with various examples.

What is inheritance in Java

Inheritance in java is a feature that helps to reuse the methods and variables of one class in another class. In other words, it allows a new class to inherit the properties and functions of an existing class without rewriting the code. It implements the parent-child relationship. This means that the child class can directly reuse the variables and functions of the parent class.

Terminologies in Java inheritance

Below are the common terms used with respect to inheritance in java.

Superclass – It is the parent class or base class from which a new class inherits the properties or methods.

Subclass – The class that extends the parent class is a subclass or child class.

extends – a keyword that supports inheritance

super – a keyword that denotes a method, constructor, or variable of a parent class.

Features of Inheritance

  • Ability to reuse the existing code of a class
  • Supports method overriding
  • Allows calling methods of superclass within methods of a subclass using super keyword.
  • Does not allow to inherit the final class or override final methods.
  • Supports multiple inheritance using interfaces.

Syntax

class A {
 //code 
} 
class B extends class A { 
 //code
 }

Class A is the base class and Class B is the child class that extends the base class. We can implement inheritance in java using the extends keyword.

Example of Java Inheritance

Below is a simple example of inheritance in java where we have created parent class with name Vehicle and child class as Car.

In the parent class, we have declared a variable name and defined 3 different methods.

We can inherit these methods in the child class by extending the parent class using the keyword extends. In this way, we can access the variables and methods directly by just using the child class object which in this case is c. If you notice, we don’t need to redeclare the variable or redefine the methods in the child class.

From this example, we can say that a car is a vehicle which means inheritance in java defines is-a relationship.

/*Filename:Vehicle.java */

public class Vehicle {
  String name;
  
  public void startVehicle() {
    System.out.println("Starting the vehicle");
  }
  
  public void applyBrakes() {
    System.out.println("Apply brakes");
  }
  
  public void stopVehicle() {
    System.out.println("Stopping the vehicle");
  }
  
}

/*Filename: Car.java */

public class Car extends Vehicle{

  public static void main(String[] args) {
    Car c = new Car();
    c.name = "BMW";
    System.out.println("Vehicle name: " + c.name);
    c.startVehicle();
    c.applyBrakes();
    c.stopVehicle();

  }

}
Vehicle name: BMW
Starting the vehicle
Apply brakes
Stopping the vehicle

We can access the protected and public variables of a parent class directly in the child class. However, if a variable in the parent class is private, then we can access this variable directly only within the same class and not from any child class. If we need to access the private variables of a parent class then we need to use the getter and setter methods of the parent class in child class.

Let’s understand this with the same example but declaring the variable name as private. In this case, we cannot directly use c.name since it will throw an error “variable is not visible”. Hence for this, we need to use the getName and setName methods to retrieve the variable value and set the value. Private, public, and protected are all access modifiers and we will discuss them in separate tutorials.

//Parent class

public class Vehicle {
  private String name;
  
  public void startVehicle() {
    System.out.println("Starting the vehicle");
  }
  
  public void applyBrakes() {
    System.out.println("Apply brakes");
  }
  
  public void stopVehicle() {
    System.out.println("Stopping the vehicle");
  }
  
  public void setName(String name) {
    this.name = name;
  }
  
  public String getName() {
    return name;
  }
}

//Child class

public class Car extends Vehicle{

  public static void main(String[] args) {
    Car c = new Car();
    c.setName("BMW");
    System.out.println("Vehicle name: " + c.getName());
    c.startVehicle();
    c.applyBrakes();
    c.stopVehicle();

  }

}
Vehicle name: BMW
Starting the vehicle
Apply brakes
Stopping the vehicle

Type of inheritance

Inheritance in java

Single inheritance

This is the simple type of inheritance in java where one class extends another class. From the pictorial representation, we can understand that class A is the base class and class B is the subclass.

Single

Example of Single Inheritance

In this example, we have a variable and a method in the parent class. We can access this from the child class using the child class’s object.

/*Filename: SingleA.java */

public class SingleA {
  public String baseclass;
  
  public void singlebaseclass() {
    System.out.println("Base class method");
  }
}

/*Filename: SingleB.java */

public class SingleB extends SingleA {
  public void singlechildclass() {
    System.out.println("Child class method");
  }

  public static void main(String[] args) {
    SingleB b = new SingleB();
    b.baseclass = "Base class name";
    System.out.println(b.baseclass);
    b.singlebaseclass(); //calls parent method
    b.singlechildclass(); //calls child method
  }

}
Base class name
Base class method
Child class method

Multilevel Inheritance

In this type of inheritance in java, the child class itself becomes a parent class of another class. From the below diagram we can understand that class A is the parent class and class B is the child class. But class B is again the parent class of class C which is the child class.

Multilevel

Example of multilevel inheritance

In this below example, we have created 3 classes. MultiA is a parent class of MultiB and MultiB is the parent class of MultiC. This means multiA is the grandparent of MultiC. Hence MultiC class can access even the methods and variables of MutliA class.

Grandparent class: /*Filename: MultiA.java*/

public class MultiA {
  public void methodA() {
    System.out.println("Method A");
  }
}

Parent class: /*Filename: MultiB.java */

public class MultiB extends MultiA {
  public void methodB() {
    System.out.println("Method B");
  }
}

Child class: /*Filename: MultiC.java */

public class MultiC extends MultiB{
  public void methodC() {
    System.out.println("Method C");
  }
  public static void main(String[] args) {
    MultiC c = new MultiC();
    c.methodA();
    c.methodB();
    c.methodC();

  }

}
Method A
Method B
Method C

Hierarchical inheritance

In this type of inheritance in java, the same parent class can have multiple child classes. From the below picture, we can understand that class A is the parent class of both class B and class C. In simple words, class A is the parent and class B and class C are the siblings.

Hierarchical

Example of hierarchical inheritance

From the below example we can see that both the child classes can access the methodA of the parent class.

/*Parent class */

public class HierarchyA {
  public void methodA() {
    System.out.println("Method A");
  }
}

/*Child class */

public class HierarchyB extends HierarchyA {

  public void methodB() {
    System.out.println("Method B");
  }
  public static void main(String[] args) {
    HierarchyB b = new HierarchyB();
    b.methodA();
    b.methodB();

  }

}
Method A
Method B

/*Child class */

public class HierarchyC extends HierarchyA{
  public void methodC() {
    System.out.println("Method C");
  }
  public static void main(String[] args) {
    HierarchyC c = new HierarchyC();
    c.methodA();
    c.methodC();

  }

}
Method A
Method C

Hybrid inheritance

Hybrid means something which has a combination. In the same way, inheritance in java can have a combination of more than 1 type. In this example, we can see that Class A is the parent of Class B and Class C which means it is a hierarchical inheritance. But class B is the parent of Class D which is single inheritance. We can also say it as a multilevel since class B is the child class of class A.

 

Hybrid

Example of hybrid inheritance

This example will clearly help you understand hybrid inheritance in java. classB has access to classA and classB methods. classC has access to classC and classA methods. classD has access to classB and classA methods. Even though classD extends the only classB, it can access classA methods since classA is the parent class of classB.

class classA {
  public void methodA() {
    System.out.println("Method A");
  }
}

class classB extends classA {
  public void methodB() {
    System.out.println("Method B");
  }
}

class classC extends classA {
  public void methodC() {
    System.out.println("Method C");
  }
  
}

class classD extends classB {
  public void methodD() {
    System.out.println("Method D");
  }
}
public class HybridExample {

  public static void main(String[] args) {
    classB b = new classB();
    classC c = new classC();
    classD d = new classD();
    System.out.println("Calling from class B");
    b.methodA();
    b.methodB();
    System.out.println("Calling from class C");
    c.methodA();
    c.methodC();
    System.out.println("Calling from class D");
    d.methodA();
    d.methodB();
    d.methodD();

  }

}
Calling from class B
Method A
Method B
Calling from class C
Method A
Method C
Calling from class D
Method A
Method B
Method D

Multiple inheritance – Not supported in java

Java does not support multiple inheritance due to the complexity and ambiguity it creates during the execution. Multiple inheritance means one class can extend more than 1 class. In other words, a child class can have more than 1 parent class. We can understand this if we compare this to real life. It is impossible for a child to have more than 1 mother. In the same way, inheritance in java cannot have 1 child class having more than 1 parent.

Multiple inheritance

 

For example, if this was allowed in java, consider the below example. When we call obj.show(), it won’t know which class method to call since it is present in both the classes.

Multiple inheritance is supported in C++. In java, we can implement this concept using interfaces which we will see towards the end of this tutorial.

class classA {
  public void show() {
    System.out.println("Class A");
  }
}
class classB {
  public void show() {
    System.out.println("Class B");
  }
}

public class MultipleInheritance extends classA,classB { //Suppose if allowed

  public static void main(String[] args) {
    MultipleInheritance obj = new MultipleInheritance();
    obj.show();

  }

}
Compile time error

Constructor in Java inheritance

We can use constructors in inheritance in java. A constructor is a special method that gets called during object creation of a class. You can refer Constructors in java tutorial to understand more about constructors.

In Java inheritance, when the constructor is present in both parent class and child class, first the constructor of the parent class is called implicitly after which it calls the constructor in the child class. We can explicitly call the constructor of the superclass by using the super keyword. If we use the super keyword, then this should be the first statement of the child constructor. We cannot use the super keyword to call an ancestral class. We can use it only for the direct parent class.

Let’s understand this with an example below. Employee class is the parent class that has a constructor and Developer is the child class which also has a constructor. Now when we create an object for Developer, it calls the constructor of Developer class from which it internally calls the Employee constructor. Hence it first prints the Employee constructor followed by the Developer constructor.

constructor in inheritance

class Employee {
  
  Employee() {
    System.out.println("I am an employee");
  }
}
public class Developer extends Employee {
  
  Developer() {
    System.out.println("I am a developer");
  }
  
  public static void main(String[] args) {
    Developer d = new Developer();
    System.out.println("This is an example of constructors in inheritance");
  }

}
I am an employee
I am a developer
This is an example of constructors in inheritance

We can also use the super keyword to explicitly call the parent class constructor as shown below which will give the same output.

class Employee {
  
  Employee() {
    System.out.println("I am an employee");
  }
}
public class Developer extends Employee {
  
  Developer() {
    super();
    System.out.println("I am a developer");
  }
  
  public static void main(String[] args) {
    Developer d = new Developer();
    System.out.println("This is an example of constructors in inheritance");
  }

}

Method overriding in Java inheritance

When both parent class and child class have the same method names with the same signatures, we call it a method overriding. Inheritance in java supports method overriding using the super keyword. When we want to call the method of the parent class we can call it using the super keyword.

Below is the syntax of using the super keyword to access the same variable name and same method name which is present in the parent class.

super.variablename;
super.methodname();


In the below example, we have the same method getEmpid in both the parent and child class. Here, Employee is the parent class and Developer is the child class. Within the child class method, we call the parent class method using the super keyword.

class Employee {
  public int empid = 111;
  Employee() {
    System.out.println("I am an employee");
  }
  public void getEmpid() {
    System.out.println("Employee id: " + empid);
  }
}
public class Developer extends Employee {
  
  public int empid = 123;
  Developer() {
    System.out.println("I am a developer");
  }
   public void getEmpid() {
     super.getEmpid();
     System.out.println("Developer id: " + empid);
   }
  
  public static void main(String[] args) {
    Developer d = new Developer();
    d.getEmpid();
    System.out.println("This is an example of method overriding in inheritance");
  }

}

I am an employee
I am a developer
Employee id: 111
Developer id: 123
This is an example of method overriding in inheritance

Interface in Java inheritance

We can use an interface to implement the concept of multiple inheritance in java. To recall the OOPs concepts that we learned in the previous tutorial, we have seen that an interface can be used to achieve abstraction where we only provide the method declaration in an interface. The class that implements the interface provides the implementation of the method.

Java allows a class to implement multiple interfaces. In this way, it supports multiple inheritance concept.

Below is a simple program to illustrate the use of an interface in multiple inheritance in java. We have defined 2 interfaces Account and Deposit each having a method accountdetails and depositdetails that do not have any code. Next, we create a class Customer that implements the 2 interfaces. For this, we use the implements keyword. We then provide the functionality of all the methods in the interface in this class. Then using the customer object, we can access both the methods.

interface Account {
  public void accountdetails();
}
interface Deposit {
  public void depositdetails();
}
public class Customer implements Account,Deposit {
  public void accountdetails() {
    System.out.println("Account details");
  }
  public void depositdetails() {
    System.out.println("Deposit Details");
  }

  public static void main(String[] args) {
    Customer c = new Customer();
    c.accountdetails();
    c.depositdetails();

  }

}
Account details
Deposit Details

Final keyword in inheritance

If a class is defined as final, then it means we cannot inherit that class or its properties and methods. We will get a compilation error if we try to extend a final class. Hence inheritance in java does not support the final class.

public final class SingleA {
  public String baseclass;
  
  public void singlebaseclass() {
    System.out.println("Base class method");
  }
}

public class SingleB extends SingleA {
  public void singlechildclass() {
    System.out.println("Child class method");
  }

  public static void main(String[] args) {
    SingleB b = new SingleB();
    b.baseclass = "Base class name";
    System.out.println(b.baseclass);
    b.singlebaseclass();
    b.singlechildclass();
  }

}
Exception in thread "main" java.lang.Error: Unresolved compilation problems: 
  baseclass cannot be resolved or is not a field
  baseclass cannot be resolved or is not a field
  The method singlebaseclass() is undefined for the type SingleB

  at SingleB.main(SingleB.java:8)

Similarly, we cannot override a method which is declared as final. Below is an example that throws compilation error when we try to override a method that is declared as final in the parent class. Hence we cannot use inheritance in java to override a final method.

class Employee {
  public int empid = 111;
  public final void getEmpid() {
    System.out.println("Employee id: " + empid);
  }
}
public class Developer extends Employee {
  
  public int empid = 123;
   public void getEmpid() {
     super.getEmpid();
     System.out.println("Developer id: " + empid);
   }
  
  public static void main(String[] args) {
    Developer d = new Developer();
    d.getEmpid();
    System.out.println("This is an example of method overriding in inheritance");
  }

}

Error: LinkageError occurred while loading main class Developer
  java.lang.VerifyError: class Developer overrides final method Employee.getEmpid()V

instanceof operator in inheritance

We can use instanceof operator in inheritance in java to check the is-a relationship. We can do this by using the interface.

Below is an example where we have an interface named fruits. Next, we create a class Seasonalfruits that implements the fruits interface. To show the concept of inheritance in java, we create a class Apple that extends the Seasonalfruits class

Now we create objects s and a for both the parent class (Seasonalfruits)and child class (Apple). The first output is true since s is part of fruits. (interface implementation). The second output is true since a is part of Seasonalfruits( single inheritance), and the third output is true since a is part of fruits (the parent class implements the interface).

interface fruits {
  
}

class Seasonalfruits implements fruits {
  
}
public class Apple extends Seasonalfruits {

  public static void main(String[] args) {
    Seasonalfruits s = new Seasonalfruits();
    Apple a = new Apple();
    System.out.println(s instanceof fruits);
    System.out.println(a instanceof Seasonalfruits);
    System.out.println(a instanceof fruits);
  }

}
true
true
true

Reference

Translate »