Understanding Different Types of Inheritance in Java

Sridhar KSridhar K
11 min read

Inheritance Types

Inheritance is a fundamental concept in object-oriented programming (OOP) that allows one class to inherit the properties and methods of another. This facilitates code reuse, enhances readability, and promotes a hierarchical classification.

Java supports various types of inheritance, each serving different design needs. If you want to understand more about inheritance, feel free to see my blog on inheritance: How Inheritance Works in Java Programming.

In this blog, we'll explore the types of inheritance in Java and their applications.

1.Single Inheritance

Definition: A single entity inherits from one parent entity.

Example: The "Father" inherits from the "Grandfather." This is the most straightforward form of inheritance and helps in maintaining a clear hierarchy.

This snapshot will clearly explain you the topic of single inheritance.

Example of Single Inheritance

Single inheritance involves one class inheriting attributes and behaviors from a single superclass, ensuring a straightforward class hierarchy and promoting code reuse in object-oriented programming.

public class Parent { // Parent class Declaration
    String hair_color="black"; // data member
    public void business() { // member function
        System.out.println("Food Business");
    }
}

class Child extends Parent { // extends keyword is used to 
    //implement inheritance
}

Explanation of the code

  1. Parent Class (Parent):

    • The Parent class declares a data member hair_color with the value "black".

    • It also defines a method business() that prints "Food Business" when called.

  2. Child Class (Child):

    • The Child class extends (inherits from) the Parent class using the extends keyword.

    • By extending Parent, the Child class inherits the hair_color data member and the business() method from Parent.

Single Inheritance implementation

public class Inherit { 

    public static void main(String[] args) {
        Parent p = new Parent(); // Create an instance of Parent class
        Child c = new Child(); // Create an instance of Child class

        // Print hair color of Parent
        System.out.println("Parent hair color: "+p.hair_color); 
        p.business(); // Call business method of Parent

        // Print inherited hair color of Child
        System.out.println("Child hair color: "+c.hair_color); 
        c.business(); // Call inherited business method of Child
    }

}

This code snippet demonstrates the use of single inheritance in Java. The Parent class has a hair_color attribute and a business method.

The Child class inherits these attributes and methods from Parent using the extends keyword. In the main method, instances of both Parent and Child classes are created and their attributes and methods are accessed.

Expected Output

Benefits of Single inheritance

  • Simplicity: Single inheritance keeps class relationships straightforward by allowing each subclass to inherit directly from one superclass, which makes code easier to understand and maintain.

  • Avoids Complexity: It prevents issues like the diamond problem, where ambiguity arises in multiple inheritance scenarios, simplifying method resolution and class hierarchy.

  • Promotes Reusability: By inheriting from a single superclass, subclasses can reuse the behavior and attributes defined in that superclass, enhancing code reuse and modularity.

  • Enhances Code Clarity: It clarifies the relationship between classes, making it easier for developers to follow and extend the functionality of classes without the complexity of multiple inheritance.

2.Multi-level Inheritance

  • Definition: An entity inherits from another entity, which in turn inherits from another entity.

  • Example: The "Son" inherits from the "Father," and the "Father" inherits from the "Grandfather." This creates a chain of inheritance, promoting a layered approach.

This snapshot will clearly explain you the topic of Multi-level inheritance.

Example of Multi-level Inheritance

Multi-level inheritance means one class inheriting from another class, which itself inherits from another class, forming a hierarchy of classes where each level adds more specific features or behaviors.

public class Animal {
    void eat() {
        System.out.println("Animal is eating");
    }
}
// Dog inherits from Animal
class Dog extends Animal {
    void bark() {
        System.out.println("Dog is barking");
    }
}
// BabyDog inherits from Dog, which in turn inherits from Animal
class BabyDog extends Dog {
    void weep() {
        System.out.println("BabyDog is weeping");
    }
}

Explanation of the Code

  1. Animal Class: Defines a base class Animal with a method eat().

  2. Dog Class: Inherits from Animal. It adds its own method bark().

  3. BabyDog Class: Inherits from Dog. It adds its own method weep().

Multi level Inheritance implementation

public class MultiLevelInheritanceExample {
    public static void main(String[] args) {
        Dog d = new Dog();
        d.eat(); // Inherited from Animal class
        d.bark(); // Inherited from Dog class

        System.out.println("========");

        BabyDog bd = new BabyDog();
        bd.eat(); // Inherited from Animal class
        bd.bark(); // Inherited from Dog class
        bd.weep(); // Specific to BabyDog class
    }
}

In this example:

  • Dog d = new Dog(); creates an instance of the Dog class.

  • d.eat(); and d.bark(); call methods inherited from the Animal and Dog classes, respectively.

  • BabyDog bd = new BabyDog(); remains unchanged from the original code snippet.

  • bd.eat();, bd.bark();, and bd.weep(); call methods inherited from the Animal, Dog, and BabyDog classes, respectively.

In this inheritance hierarchy:

  • Animal serves as the base class defining a generic behavior eat().

  • Dog extends Animal to inherit eat() and adds bark(), which is specific to dogs.

  • BabyDog further extends Dog, inheriting both eat() and bark(), and introduces weep(), which is specific to baby dogs.

Expected Output

Benefits of Multi-level Inheritance

  • Code Reusability: Methods and attributes defined in parent classes can be reused in subclasses, reducing redundancy.

  • Hierarchy: Establishes a clear hierarchical relationship among classes, making the code more organized and easier to maintain.

  • Extensibility: Allows for extending functionality by adding new methods or

3. Hierarchical Inheritance

  • Definition: Multiple entities inherit from a single parent entity.

  • Example: Both the "Father" and an "Uncle" inherit from the "Grandfather." This is useful for creating a common base for different entities that share common features.

Here in this example both the Front-end developer and Back-end Developer are the child classes of Developer class.

Example of Hierarchical Inheritance

It is a type of inheritance in which one parent class will be inherited by multiple child classes.

Developer Parent Class

public class Developer { // Parent Class
    public void code() {
        System.out.println("Developer is coding");
    }
}

Developer class is a parent class which has a method code() which prints a statement "Developer is coding".

FrontendDeveloper Child Class

// FrontendDeveloper.java - Child Class 1
public class FrontendDeveloper extends Developer {
    public void frontendProject() {
        System.out.println("Frontend Developer is doing a frontend project");
    }
}

The FrontendDeveloper class is one of the child classes of the Developer class, which has a specific method called frontendProject().

BackendDeveloper Child Class

//BackendDeveloper.java - Child Class 2
public class BackendDeveloper extends Developer {
 public void backendProject() {
     System.out.println("Backend Developer is doing a backend project");
 }
}

The BackendDeveloper class is one of the child classes of the Developer class, which has a specific method called backendProject().

Hierarchical Inheritance Implementation

public class Main {
    public static void main(String[] args) {
        Developer dev = new Developer();
        dev.code();

        FrontendDeveloper feDev = new FrontendDeveloper();
        feDev.code(); // Inherited method from Developer
        feDev.frontendProject();

        BackendDeveloper beDev = new BackendDeveloper();
        beDev.code(); // Inherited method from Developer
        beDev.backendProject();
    }
}

Class Definitions and Instantiation

  • Developer Class: The Developer class is instantiated with Developer dev = new Developer();. This creates an object dev of type Developer.

  • FrontendDeveloper Class: The FrontendDeveloper class, a child class of Developer, is instantiated with FrontendDeveloper feDev = new FrontendDeveloper();. This creates an object feDev of type FrontendDeveloper.

  • BackendDeveloper Class: Similarly, the BackendDeveloper class, another child class of Developer, is instantiated with BackendDeveloper beDev = new BackendDeveloper();, creating an object beDev of type BackendDeveloper.

Method Invocation:

  • Inherited Method: Both FrontendDeveloper and BackendDeveloper inherit the code() method from the Developer class. Thus, feDev.code() and beDev.code() call the code() method defined in the Developer class, printing "Developer is coding" to the console.

  • Child-Specific Methods:

    • feDev.frontendProject() calls the frontendProject() method specific to the FrontendDeveloper class, performing actions related to frontend project tasks.

    • beDev.backendProject() calls the backendProject() method specific to the BackendDeveloper class, performing actions related to backend project tasks.

Developer class has more than one child class hence it is a perfect example for hierarchical inheritance.

Expected output

Developer is coding
Developer is coding
Frontend Developer is doing a frontend project
Developer is coding
Backend Developer is doing a backend project

Benefits of Hierarchical Inheritance

  • Code Reusability: Subclasses inherit attributes and behaviors from a superclass, reducing redundancy and promoting reuse of common functionalities across related classes.

  • Organizational Structure: Establishes a clear hierarchy among classes, improving the organization and management of relationships between different types of objects in the system.

  • Eases Maintenance: Changes made to the superclass propagate automatically to its subclasses, reducing the effort required to update shared functionalities and ensuring consistency across the application.

4. Hybrid Inheritance

  • Definition: A combination of two or more types of inheritance.

  • Example: Combining hierarchical and multi-level inheritance in a single structure. For instance, the "Son" inherits from the "Father" (multi-level), and the "Father" and an "Uncle" both inherit from the "Grandfather" (hierarchical). This allows for more complex structures, integrating multiple inheritance strategies.

This is an example of hybrid inheritance. Hybrid inheritance is a combination of single, multiple and multi-level inheritance.

Hybrid inheritance combines different types of inheritance single, multi-level, and hierarchical to create flexible class relationships and organize code efficiently in object-oriented programming.

Example of Hybrid Inheritance

Developer Parent Class

// Parent class
class Developer {
    public void code() {
        System.out.println("Developer is coding");
    }
}

FrontendDeveloper Child Class

// Child class inheriting from Developer
class FrontendDeveloper extends Developer {
    public void frontendProject() {
        System.out.println("Frontend Developer is working on frontend project");
    }
}

BackendDeveloper Child Class

// BackendDeveloper.java - Child Class 2
public class BackendDeveloper extends Developer {
    public void backendProject() {
        System.out.println("Backend Developer is doing a backend project");
    }
}

JavaDeveloper Child Class

// JavaDeveloper.java - Child Class of BackendDeveloper
public class JavaDeveloper extends BackendDeveloper {
    public void javaProject() {
        System.out.println("Java Developer is doing a Java project");
    }
}

Hybrid Inheritance Implementation

// Main.java - Testing the Classes
public class Main {
    public static void main(String[] args) {
        Developer dev = new Developer();
        dev.code();

        FrontendDeveloper feDev = new FrontendDeveloper();
        feDev.code(); // Inherited method from Developer
        feDev.frontendProject();

        BackendDeveloper beDev = new BackendDeveloper();
        beDev.code(); // Inherited method from Developer
        beDev.backendProject();

        JavaDeveloper javaDev = new JavaDeveloper();
        javaDev.code(); // Inherited method from Developer
        javaDev.backendProject(); // Inherited method from BackendDeveloper
        javaDev.javaProject(); // Method from JavaDeveloper
    }
}

Explanation

  1. Developer Class:

    • Acts as the parent class with a method code() that prints "Developer is coding".
  2. FrontendDeveloper Class:

    • Inherits from Developer and adds frontendProject() method to handle frontend-specific tasks. When feDev.code() is called, it invokes the code() method from Developer, and feDev.frontendProject() prints "Frontend Developer is working on a frontend project".
  3. BackendDeveloper Class:

    • Inherits from Developer and adds backendProject() method for backend-specific tasks. When beDev.code() is called, it also invokes the code() method from Developer, and beDev.backendProject() prints "Backend Developer is working on a backend project".
  4. JavaDeveloper Class:

    • Inherits from BackendDeveloper and introduces javaProject() method specific to Java development tasks. When javaDev.code() is called, it invokes the code() method from Developer. javaDev.backendProject() invokes the backendProject() method from BackendDeveloper, and javaDev.javaProject() prints "Java Developer is doing a Java project".

Expected Output

Developer is coding
Developer is coding
Frontend Developer is working on a frontend project
Developer is coding
Backend Developer is working on a backend project
Java Developer is doing a Java project

Benefits of Hybrid Inheritance

  • Code Reusability: Hybrid inheritance lets subclasses inherit features from multiple parent classes, reducing the need to repeat code and promoting efficient programming.

  • Enhanced Flexibility: It supports both vertical (single) and horizontal (multiple) inheritance, allowing developers to create intricate class structures that meet diverse needs and encourage modular design.

  • Specialization and Organization: Subclasses can inherit and refine behaviors from different parts of the inheritance tree, promoting specialized and well-organized code that's easier to maintain and extend.

5. Multiple Inheritance

  • Definition: An entity inherits from more than one parent entity.

  • Example:(Note: Java does not support multiple inheritance directly due to ambiguity issues, but it can be achieved using interfaces.) If the "Son" implements both "FatherlyDuties" and "UnclelyDuties" interfaces, it can achieve multiple inheritance-like behavior.

  • In Java, multiple inheritance means a class inheriting from more than one class. However, Java doesn't allow a class to directly inherit from multiple classes due to complexity issues such as the diamond shape problem and ambiguity.

  • Instead, Java uses interfaces for multiple inheritance. Interfaces define what methods a class must implement, allowing a class to inherit behavior from multiple interfaces while avoiding conflicts that could arise from inheriting state (data).

  • This approach promotes code flexibility and reusability while maintaining clarity and avoiding potential issues like the diamond problem.

    This image clearly explains that one child class, Developer, is inheriting from two parent classes, namely FrontendDeveloper and BackendDeveloper. By default, these two classes have the Object class as their parent class.

    Interfaces in java do not have a default parent class. So one can achieve multiple inheritance by using interfaces.

6. Cyclic Inheritance

  • Definition: An entity inherits from more than one parent entity.

  • Example:(Note: Java does not support multiple inheritance directly due to ambiguity issues, but it can be achieved using interfaces.) If the "Son" implements both "FatherlyDuties" and "UnclelyDuties" interfaces, it can achieve multiple inheritance-like behavior.

  • Cyclic inheritance occurs when a class ends up being an ancestor of itself, creating a loop. This leads to logical errors and confusion.

  • Java prevents cyclic inheritance by not allowing a class to be its own ancestor, ensuring a clear and logical inheritance hierarchy.

  • This safeguard helps maintain code clarity and prevents design flaws, making your programs more reliable and easier to understand.

This image clearly explains about the cyclic inheritance. Also cyclic inheritance is not allowed in java.

Conclusion

In object-oriented programming, inheritance allows a class to use properties and methods from another class. There are several types:

  1. Single Inheritance: A class inherits from one parent class.

  2. Multiple Inheritance: A class inherits from multiple parent classes (Java does this with interfaces).

  3. Multi-level Inheritance: A class inherits from a class that is also a subclass.

  4. Hierarchical Inheritance: Multiple classes inherit from a single parent class.

  5. Hybrid Inheritance: Combines multiple types of inheritance.

Inheritance is used to organize code, promote reuse, and make maintenance easier, but they need to be used carefully to avoid confusion and errors.

0
Subscribe to my newsletter

Read articles from Sridhar K directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Sridhar K
Sridhar K

I am a fresher Software developer with a strong foundation in Java, HTML, CSS, and JavaScript. I have experience with various libraries and frameworks, including Spring Boot, Express.js, Node.js, Hibernate, MySQL, and PostgreSQL. I am eager to leverage my technical skills and knowledge to contribute effectively to a dynamic development team. I am committed to continuous learning and am excited to begin my career in a challenging developer role.