BhauAutomation

Java Inheritance

Inheritance in Java is a core Object-Oriented Programming (OOP) concept that allows a class to acquire properties and methods of another class. It promotes code reusability, establishes parent-child relationships, and enables method overriding for runtime polymorphism.

📘 Topic: Core Java / OOPs
Read time: 7 min
📊 Level: Intermediate
🏛️ Focus: Code Reusability
📖 Overview

What is Inheritance in Java?

Inheritance is a mechanism where one class (child/subclass) inherits the properties and methods of another class (parent/superclass). The keyword used for inheritance in Java is extends. This relationship promotes code reuse and logical organization of classes.

The class being inherited from is called the parent class or superclass, and the class that inherits is called the child class or subclass. Java supports single inheritance (one child can have only one direct parent) but allows multiple inheritance through interfaces.

🔑 Keywords

Important Keywords in Inheritance

🔹 extends

Used to inherit properties and methods from a parent class. Example: class Dog extends Animal { }

🔹 super

Used to refer to the immediate parent class object. Used to access parent class variables, methods, and constructors.

🔹 method overriding

When a child class provides a specific implementation of a method that is already defined in its parent class.

🎯 Objectives

Objectives of Inheritance

🔁 Code Reusability: The main objectives of using inheritance are to reduce code duplication by reusing existing code from parent classes.

📦 Organized Code: It helps organize code efficiently by establishing hierarchical relationships between classes.

🔄 Runtime Polymorphism: Enables method overriding and runtime polymorphism, where a parent reference can point to a child object.

✅ Advantages

Advantages of Inheritance

📝 Reduces Code Redundancy: Common code can be written once in the parent class and reused by multiple child classes.

🔧 Enhances Maintainability: Changes made in the parent class automatically propagate to all child classes, making maintenance easier.

🎭 Supports Method Overriding: Child classes can provide specific implementations of parent class methods, enabling runtime polymorphism.

🏗️ Promotes Extensibility: New features can be added to child classes without modifying existing parent class code.

For example, a Dog class can inherit from Animal class, reusing its eat() method while adding new behavior like bark(). Similarly, Cat can inherit from Animal and add meow().

⚠️ Limitations

Limitations of Inheritance

🔗 Tight Coupling: Inheritance leads to tight coupling between parent and child classes. Changes in the parent can break child classes.

📈 Increased Complexity: Improper use of inheritance can increase code complexity and make the system harder to understand.

🚫 Single Inheritance Restriction: Java does not support multiple class inheritance (a class cannot extend more than one class), which can be limiting in some designs.

🎯 Not Always Appropriate: Not all relationships fit an IS-A model; sometimes composition is a better choice than inheritance.

📂 Types

Types of Inheritance in Java

🏛️ Single Inheritance

One child class inherits from one parent class. Example: class B extends A { }

🔗 Multilevel Inheritance

A chain where class B inherits from class A, and class C inherits from class B. Example: A → B → C

🌳 Hierarchical Inheritance

Multiple child classes inherit from a single parent class. Example: B extends A, C extends A

📋 Multiple Inheritance (through Interfaces)

Java does not support multiple class inheritance directly, but a class can implement multiple interfaces: class C implements A, B { }

💻 Code Example

Inheritance Example in Java

// Parent class
class Animal {
    String name;
    
    void eat() {
        System.out.println(name + " is eating...");
    }
    
    void sleep() {
        System.out.println(name + " is sleeping...");
    }
}

// Single Inheritance - Child class
class Dog extends Animal {
    void bark() {
        System.out.println(name + " is barking...");
    }
    
    // Method overriding
    @Override
    void eat() {
        System.out.println(name + " is eating dog food...");
    }
}

// Hierarchical Inheritance - Another child class
class Cat extends Animal {
    void meow() {
        System.out.println(name + " is meowing...");
    }
}

// Multilevel Inheritance
class Puppy extends Dog {
    void play() {
        System.out.println(name + " is playing...");
    }
}

// Using super keyword example
class Vehicle {
    String brand = "Generic Vehicle";
    
    Vehicle() {
        System.out.println("Vehicle constructor called");
    }
    
    void display() {
        System.out.println("Brand: " + brand);
    }
}

class Car extends Vehicle {
    String brand = "Toyota";
    
    Car() {
        super(); // Calls parent class constructor
        System.out.println("Car constructor called");
    }
    
    void display() {
        super.display(); // Calls parent class display method
        System.out.println("Car Brand: " + brand);
    }
}

public class InheritanceDemo {
    public static void main(String[] args) {
        System.out.println("=== Dog Example ===");
        Dog dog = new Dog();
        dog.name = "Buddy";
        dog.eat();    // Overridden method
        dog.sleep();  // Inherited method
        dog.bark();   // Child's own method
        
        System.out.println("\n=== Cat Example ===");
        Cat cat = new Cat();
        cat.name = "Whiskers";
        cat.eat();    // Inherited method
        cat.meow();   // Child's own method
        
        System.out.println("\n=== Puppy Example (Multilevel) ===");
        Puppy puppy = new Puppy();
        puppy.name = "Max";
        puppy.eat();   // Inherited from Dog (overridden)
        puppy.bark();  // Inherited from Dog
        puppy.play();  // Puppy's own method
        
        System.out.println("\n=== super Keyword Example ===");
        Car car = new Car();
        car.display();
    }
}
🏆 Best Practices

Best Practices for Using Inheritance

Use inheritance only when there is a clear IS-A relationship between classes

Prefer composition over inheritance when the relationship is HAS-A

Keep parent classes general and child classes specific

Use the @Override annotation to indicate method overriding clearly

Mark classes as final to prevent inheritance if not designed for it

Avoid deep inheritance hierarchies; keep the depth to 2-3 levels maximum