;
Java Intermediate July 25 ,2025

 Inheritance in Java

1. Introduction

Inheritance is one of the core concepts of Object-Oriented Programming (OOP). It allows a new class (called a subclass or derived class) to acquire the properties and behaviors (fields and methods) of an existing class (called a superclass or base class).

2. Why Use Inheritance in Java?

  • Code Reusability: Reuse existing code by inheriting from existing classes.
  • Improved Maintainability: Changes made to the superclass are automatically reflected in the subclass.
  • Extensibility: Create more specific behaviors by extending general ones.
  • Polymorphism: Enables method overriding and dynamic method dispatch.

3. How Inheritance Works in Java?

In Java, inheritance is a fundamental object-oriented programming concept that allows one class to acquire the properties and behaviors (fields and methods) of another class. It is used to promote code reusability and logical hierarchy between classes. The class that inherits the features is called the subclass (or child class), and the class from which it inherits is known as the superclass (or parent class). Java implements inheritance using the extends keyword. When a subclass extends a superclass, it automatically gains access to all non-private members (variables and methods) of the superclass. This means the subclass can use, modify, or override the inherited methods, while also adding its own specific functionality. Inheritance helps in building a natural classification of objects, encourages reuse of existing code, and enables polymorphism. Java supports single, multilevel, and hierarchical inheritance but does not allow multiple inheritance with classes to avoid ambiguity; instead, it supports multiple inheritance through interfaces. Overall, inheritance enhances modularity, reduces redundancy, and makes it easier to manage and scale complex applications..

class Animal {
    void eat() {
        System.out.println("This animal eats food");
    }
}

class Dog extends Animal {
    void bark() {
        System.out.println("The dog barks");
    }
}

public class Main {
    public static void main(String[] args) {
        Dog d = new Dog();
        d.eat();  // inherited method
        d.bark(); // own method
    }
}

Output:

This animal eats food
The dog barks

4. Syntax of Inheritance in Java

Inheritance in Java is implemented using the extends keyword. This keyword allows one class (the subclass) to inherit fields and methods from another class (the superclass). The syntax is simple and establishes a parent-child relationship between the two classes. The subclass gains access to all non-private members of the superclass, which means it can use those fields and methods as if they were defined in the subclass itself. This setup supports reusability of code and hierarchical classification of classes. The subclass can also define its own additional fields and methods to extend or specialize the behavior of the superclass. Java allows single inheritance through classes, meaning a class can inherit from only one superclass at a time, but a superclass can have multiple subclasses.

class Superclass {
    // fields and methods
}

class Subclass extends Superclass {
    // additional fields and methods
}
  • Superclass defines the general structure or behavior.
  • Subclass inherits that structure and can add more specific features.

Example


class Vehicle {
    void move() {
        System.out.println("Vehicle is moving");
    }
}

class Car extends Vehicle {
    void speed() {
        System.out.println("Car is running at 80 km/h");
    }
}

public class Main {
    public static void main(String[] args) {
        Car c = new Car();
        c.move();  // inherited method
        c.speed(); // own method
    }
}

Output

Vehicle is moving
Car is running at 80 km/h

 

5. Types of Inheritance in Java

a. Single Inheritance

In single inheritance, a subclass inherits from only one superclass. This is the most basic form of inheritance where there is a one-to-one parent-child relationship. The subclass has access to all non-private fields and methods of the superclass. It helps promote code reusability and method sharing between classes.

Code:

class Parent {
    void message() {
        System.out.println("This is parent class");
    }
}

class Child extends Parent {
    void display() {
        System.out.println("This is child class");
    }
}

public class Main {
    public static void main(String[] args) {
        Child c = new Child();
        c.message();
        c.display();
    }
}

Output:

This is parent class  
This is child class

b. Multilevel Inheritance

In multilevel inheritance, a class inherits from a subclass which itself inherits from another superclass. This forms a chain of inheritance like grandparent → parent → child. It allows transfer of properties across multiple levels in a class hierarchy. Each subclass gets access to the methods of all its superclasses.

Code:

class Grandparent {
    void grandparentMethod() {
        System.out.println("Grandparent class");
    }
}

class Parent extends Grandparent {
    void parentMethod() {
        System.out.println("Parent class");
    }
}

class Child extends Parent {
    void childMethod() {
        System.out.println("Child class");
    }
}

public class Main {
    public static void main(String[] args) {
        Child c = new Child();
        c.grandparentMethod();
        c.parentMethod();
        c.childMethod();
    }
}

Output:

Grandparent class  
Parent class  
Child class

c. Hierarchical Inheritance

In hierarchical inheritance, multiple subclasses inherit from a single superclass. Each subclass gets access to the parent class’s members but operates independently from other subclasses. This type of inheritance helps create a base class with general behavior and extend it differently in multiple directions.

Code:

class Parent {
    void parentMethod() {
        System.out.println("Parent class method");
    }
}

class Child1 extends Parent {
    void child1Method() {
        System.out.println("Child1 class method");
    }
}

class Child2 extends Parent {
    void child2Method() {
        System.out.println("Child2 class method");
    }
}

public class Main {
    public static void main(String[] args) {
        Child1 c1 = new Child1();
        c1.parentMethod();
        c1.child1Method();

        Child2 c2 = new Child2();
        c2.parentMethod();
        c2.child2Method();
    }
}

Output:

Parent class method  
Child1 class method  
Parent class method  
Child2 class method

d. Hybrid Inheritance (Achieved Using Interfaces)

Hybrid inheritance is a combination of two or more types of inheritance. Since Java does not support multiple inheritance with classes (to avoid ambiguity caused by the diamond problem), hybrid inheritance is implemented using interfaces. This allows a class to implement multiple interfaces, thereby achieving hybrid behavior with no confusion or conflict.

Diamond Problem in Hybrid Inheritance

The diamond problem occurs when a class inherits from two classes that both inherit from a common superclass, leading to ambiguity about which version of the method should be inherited.

Java avoids this issue by not allowing multiple class inheritance. Instead, when multiple interfaces have the same method, the implementing class must explicitly override it, eliminating ambiguity.

Code:

interface A {
    void methodA();
}

interface B {
    void methodA(); // Same method as in A
}

class C implements A, B {
    // Must override methodA to resolve conflict
    public void methodA() {
        System.out.println("Method A from C");
    }
}

public class Main {
    public static void main(String[] args) {
        C obj = new C();
        obj.methodA();
    }
}

Output:

Method A from C

Explanation:

In the above example, both interface A and interface B declare the same method methodA(). When class C implements both interfaces, Java forces it to provide its own implementation of methodA(). This way, there is no ambiguity like in multiple class inheritance, and the diamond problem is avoided.

 

6. The super Keyword in Java

In Java, the super keyword is used to refer to the immediate parent class of a subclass. It serves two primary purposes:

  1. Accessing Parent Class Members:
    If a subclass has a field or method with the same name as one in the parent class, super is used to explicitly refer to the parent class’s version.
  2. Calling Parent Class Constructor:
    The super() statement is used inside a subclass constructor to invoke the constructor of the parent class. This ensures that the parent class is properly initialized before executing the subclass constructor. If not explicitly written, the compiler automatically inserts a no-argument super() call as the first statement in the subclass constructor (only if the parent class has a no-argument constructor).
Super Keyword in Java. The super keyword in Java is a… | by Nikhil Sambhaji  Salvi | Medium

Example Code

class Parent {
    Parent() {
        System.out.println("Parent constructor");
    }
}

class Child extends Parent {
    Child() {
        super(); // Calls the constructor of Parent class
        System.out.println("Child constructor");
    }
}

public class Main {
    public static void main(String[] args) {
        Child c = new Child();
    }
}

Output

Parent constructor  
Child constructor

Explanation of Output

  • When a Child object is created using new Child(), its constructor is called.
  • Inside the Child constructor, super() is the first statement. This triggers the Parent class constructor.
  • So first, Parent constructor is printed.
  • After that, the rest of the Child constructor is executed, printing Child constructor.

 

7. Java IS-A Relationship

In Java, an IS-A relationship represents inheritance between classes — a way to express that one class is a type of another. When a subclass inherits from a superclass using the extends keyword (or implements an interface using implements), it forms an IS-A relationship. This implies that the subclass object can be treated as an instance of the parent class because it inherits its properties and behaviors. IS-A is a fundamental concept in object-oriented programming that supports polymorphism and code reuse.

For example, if class Dog extends class Animal, then we say:
A Dog IS-A Animal — because it inherits the characteristics of Animal.

This relationship allows for writing flexible and reusable code where objects can be referred to by their parent type.

Example

class Animal {
    void eat() {
        System.out.println("Animal eats");
    }
}

class Dog extends Animal {
    void bark() {
        System.out.println("Dog barks");
    }
}

public class Main {
    public static void main(String[] args) {
        Dog d = new Dog(); // Dog IS-A Animal
        d.eat();  // inherited method
        d.bark(); // own method
    }
}

Output

Animal eats  
Dog barks

Explanation

  • Dog extends Animal, so it is a type of Animal.
  • Therefore, a Dog object d can access both eat() (from Animal) and bark() (from Dog).
  • This IS-A relationship enables Dog to behave like an Animal wherever required.

8. Constructors and Inheritance

In Java, constructors are not inherited by subclasses. While a subclass can inherit fields and methods from its superclass, constructors are special methods used to initialize objects and are not passed down through inheritance. However, a subclass must call a constructor of its superclass, either explicitly using the super() keyword or implicitly if no constructor is defined.

If the superclass has a no-argument constructor, the Java compiler automatically inserts a call to super() in the subclass constructor. But if the superclass only provides a parameterized constructor, the subclass must explicitly call it using super(arguments); otherwise, a compilation error will occur.

This ensures that the parent class is initialized properly before the subclass adds its own initialization logic. The super() call must be the first statement in the subclass constructor.

Example:

class Parent {
    Parent() {
        System.out.println("Parent constructor");
    }
}

class Child extends Parent {
    Child() {
        super();  // optional here, as Parent() is a no-arg constructor
        System.out.println("Child constructor");
    }
}

public class Main {
    public static void main(String[] args) {
        Child c = new Child();
    }
}

Output:

Parent constructor  
Child constructor

 

9. Method Overriding in Inheritance

Method overriding in Java occurs when a subclass provides a specific implementation of a method that is already defined in its superclass. The method in the subclass must have the same name, return type, and parameter list as the method in the parent class. Overriding allows the subclass to modify or extend the behavior of the inherited method, making it suitable for its own use.

When a method is called using an object of the subclass, the overridden version in the subclass is executed, not the one in the parent class. This supports runtime polymorphism, where the decision of which method to call is made at runtime based on the object type.

Method Overriding in Java

Example:

class Animal {
    void sound() {
        System.out.println("Animal makes a sound");
    }
}

class Dog extends Animal {
    void sound() {
        System.out.println("Dog barks");
    }
}

public class Main {
    public static void main(String[] args) {
        Dog d = new Dog();
        d.sound(); // Calls the overridden method in Dog
    }
}

Output:

Dog barks

Explanation of Output

  • The sound() method is defined in both Animal and Dog classes.
  • Since Dog overrides the sound() method, the Dog's version is called when d.sound() is executed.
  • Even though Dog is a subclass of Animal, its own version of sound() takes precedence due to overriding.
     

10. Inheritance vs Composition

  • Inheritance: “is-a” relationship.
  • Composition: “has-a” relationship.

Use composition when behavior can be reused without extending.

11. Access Modifiers and Inheritance

  • public: accessible everywhere.
  • protected: accessible in subclass and same package.
  • default: accessible in the same package.
  • private: not accessible in subclass.

12. Advantages of Inheritance

  • Promotes code reusability.
  • Reduces code redundancy.
  • Improves maintainability.
  • Supports polymorphism.

13. Disadvantages of Inheritance

  • Increases coupling between parent and child class.
  • Misuse can lead to fragile or tightly coupled code.
  • Overuse may make code harder to understand and maintain.

14. Common Mistakes & Best Practices

  • Don’t use inheritance when composition is more appropriate.
  • Don’t override methods unnecessarily.
  • Always use access modifiers appropriately.
  • Use super carefully.
  • Keep class hierarchy shallow if possible.

Conclusion

Inheritance is a fundamental concept in Java and one of the key pillars of object-oriented programming. It promotes code reusability, scalability, and better organization of your codebase. By allowing a subclass to inherit fields and methods from a superclass, Java enables developers to create hierarchical class structures that reflect real-world relationships.

Understanding inheritance not only helps reduce code duplication but also allows for easier maintenance and enhancement of applications. With features like method overriding, the use of super, and support for multilevel and hierarchical inheritance, Java provides powerful tools to build flexible and robust software systems.

Mastering inheritance is essential for any Java developer aiming to write clean, efficient, and modular code.

 

Next Blog-   Polymorphism in Java

Sanjiv
0

You must logged in to post comments.

Get In Touch

123 Street, New York, USA

+012 345 67890

techiefreak87@gmail.com

© Design & Developed by HW Infotech