Java Inheritance

Introduction

Inheritance is one of the four fundamental principles of Object-Oriented Programming (OOP) in Java. It allows a new class (subclass or derived class) to inherit properties and behaviors (fields and methods) from an existing class (superclass or base class). Inheritance promotes code reusability and establishes a natural hierarchical relationship between classes.

Table of Contents

  1. What is Inheritance?
  2. Benefits of Inheritance
  3. Implementing Inheritance in Java
  4. Types of Inheritance in Java
  5. The super Keyword
  6. Method Overriding
  7. Real-World Examples
  8. Conclusion

1. What is Inheritance?

Inheritance is a mechanism in Java by which one class (the subclass) can inherit the fields and methods of another class (the superclass). This allows the subclass to reuse code from the superclass without having to rewrite it. The subclass can also add its own fields and methods or override existing ones.

2. Benefits of Inheritance

  • Code Reusability: Inheritance allows you to reuse code from existing classes, reducing redundancy.
  • Method Overriding: Subclasses can provide specific implementations for methods defined in the superclass.
  • Hierarchical Organization: Inheritance helps to organize classes in a hierarchical manner, making the code more understandable and maintainable.

3. Implementing Inheritance in Java

Inheritance is implemented using the extends keyword.

Example:

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

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

public class Main {
    public static void main(String[] args) {
        Dog myDog = new Dog();
        myDog.eat();
        myDog.bark();
    }
}

Output:

This animal eats food.
The dog barks.

4. Types of Inheritance in Java

Java supports the following types of inheritance:

1. Single Inheritance

In a single inheritance, a subclass inherits from one superclass. This is the simplest form of inheritance.

Definition

Single inheritance refers to a class inheriting from only one superclass. It is used to extend the functionality of a single base class by adding new features or overriding existing ones.

Example:

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

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

public class Main {
    public static void main(String[] args) {
        Dog myDog = new Dog();
        myDog.eat();
        myDog.bark();
    }
}

2. Multilevel Inheritance

In multilevel inheritance, a class is derived from another class, which is also derived from another class, forming a chain of inheritance.

Definition

Multilevel inheritance refers to a scenario where a class inherits from a subclass, making it part of a longer inheritance chain. This type of inheritance can extend the hierarchy and add layers of functionality.

Example:

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

// Intermediate subclass
public class Mammal extends Animal {
    public void breathe() {
        System.out.println("This mammal breathes air.");
    }
}

// Final subclass
public class Dog extends Mammal {
    public void bark() {
        System.out.println("The dog barks.");
    }
}

public class Main {
    public static void main(String[] args) {
        Dog myDog = new Dog();
        myDog.eat();
        myDog.breathe();
        myDog.bark();
    }
}

3. Hierarchical Inheritance

In hierarchical inheritance, multiple subclasses inherit from a single superclass.

Definition

Hierarchical inheritance occurs when multiple subclasses share the same superclass. It allows the subclasses to inherit common features from the superclass while also adding their own unique features.

Example:

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

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

// Subclass 2
public class Cat extends Animal {
    public void meow() {
        System.out.println("The cat meows.");
    }
}

public class Main {
    public static void main(String[] args) {
        Dog myDog = new Dog();
        Cat myCat = new Cat();
        myDog.eat();
        myDog.bark();
        myCat.eat();
        myCat.meow();
    }
}

4. Multiple Inheritance (Using Interfaces)

Java does not support multiple inheritance (a class inheriting from more than one class) directly to avoid complexity and ambiguity. However, multiple inheritance can be achieved using interfaces.

Definition

Multiple inheritance refers to a class inheriting from multiple classes. Java does not support multiple inheritance directly due to the “diamond problem,” but it can be simulated using interfaces. A class can implement multiple interfaces, thus achieving multiple inheritance-like behavior.

Example:

// Interface 1
interface CanFly {
    void fly();
}

// Interface 2
interface CanSwim {
    void swim();
}

// Class implementing multiple interfaces
public class Duck implements CanFly, CanSwim {
    public void fly() {
        System.out.println("The duck flies.");
    }

    public void swim() {
        System.out.println("The duck swims.");
    }
}

public class Main {
    public static void main(String[] args) {
        Duck myDuck = new Duck();
        myDuck.fly();
        myDuck.swim();
    }
}

5. The super Keyword

The super keyword in Java is used to refer to the immediate superclass of a subclass. It is commonly used to access superclass methods and constructors.

Example: Using super to Call Superclass Constructor

// Superclass
public class Animal {
    String name;

    // Constructor
    public Animal(String name) {
        this.name = name;
    }

    public void display() {
        System.out.println("Animal: " + name);
    }
}

// Subclass
public class Dog extends Animal {
    String breed;

    // Constructor
    public Dog(String name, String breed) {
        super(name); // Call to superclass constructor
        this.breed = breed;
    }

    public void display() {
        super.display(); // Call to superclass method
        System.out.println("Breed: " + breed);
    }
}

public class Main {
    public static void main(String[] args) {
        Dog myDog = new Dog("Buddy", "Golden Retriever");
        myDog.display();
    }
}

Output:

Animal: Buddy
Breed: Golden Retriever

6. Method Overriding

Method overriding occurs when a subclass provides a specific implementation for a method that is already defined in its superclass. The overridden method in the subclass must have the same signature (name, return type, and parameters) as the method in the superclass.

Example: Method Overriding

// Superclass
public class Animal {
    public void sound() {
        System.out.println("This animal makes a sound.");
    }
}

// Subclass
public class Cat extends Animal {
    @Override
    public void sound() {
        System.out.println("The cat meows.");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal myCat = new Cat();
        myCat.sound();
    }
}

Output:

The cat meows.

7. Real-World Examples

Example: Vehicle Inheritance

Let’s implement a real-world example of inheritance in Java using a simple hierarchy of a vehicle.

Let’s say we have a basic Vehicle class, and we want to create specific types of vehicles like Car and Bike that inherit properties from Vehicle.

1. Vehicle Class (Parent Class)

class Vehicle {
    String brand;
    int speed;

    // Constructor
    public Vehicle(String brand, int speed) {
        this.brand = brand;
        this.speed = speed;
    }

    // Method to display vehicle details
    public void displayInfo() {
        System.out.println("Brand: " + brand + ", Speed: " + speed + " km/h");
    }
}

2. Car Class (Child Class)

class Car extends Vehicle {
    int numberOfDoors;

    // Constructor
    public Car(String brand, int speed, int numberOfDoors) {
        super(brand, speed);  // Calling the constructor of the parent class
        this.numberOfDoors = numberOfDoors;
    }

    // Method to display car details
    @Override
    public void displayInfo() {
        super.displayInfo();  // Calling the method of the parent class
        System.out.println("Number of Doors: " + numberOfDoors);
    }
}

3. Bike Class (Child Class)

class Bike extends Vehicle {
    boolean hasCarrier;

    // Constructor
    public Bike(String brand, int speed, boolean hasCarrier) {
        super(brand, speed);  // Calling the constructor of the parent class
        this.hasCarrier = hasCarrier;
    }

    // Method to display bike details
    @Override
    public void displayInfo() {
        super.displayInfo();  // Calling the method of the parent class
        System.out.println("Has Carrier: " + (hasCarrier ? "Yes" : "No"));
    }
}

4. Main Class to Test Inheritance

public class Main {
    public static void main(String[] args) {
        Car car = new Car("Toyota", 120, 4);
        Bike bike = new Bike("Yamaha", 80, true);

        System.out.println("Car Details:");
        car.displayInfo();

        System.out.println("\nBike Details:");
        bike.displayInfo();
    }
}

Output:

Car Details:
Brand: Toyota, Speed: 120 km/h
Number of Doors: 4

Bike Details:
Brand: Yamaha, Speed: 80 km/h
Has Carrier: Yes

Explanation:

  1. Vehicle Class:
    • The Vehicle class is the parent class with common properties like brand and speed.
    • It has a method displayInfo() that prints these properties.
  2. Car and Bike Classes:
    • Both Car and Bike classes inherit from Vehicle using the extends keyword.
    • They each have their own specific properties (numberOfDoors for Car and hasCarrier for Bike).
    • They override the displayInfo() method to include their specific details while still calling the parent class’s method using super.displayInfo().
  3. Main Class:
    • This class creates instances of Car and Bike, and calls their displayInfo() methods to show the inherited and specific properties.

This example demonstrates how inheritance allows Car and Bike to reuse code from the Vehicle class while adding their own specific properties and behaviors. This is a fundamental concept in object-oriented programming that helps reduce code duplication and improve maintainability.

Real-World Example of Java Inheritance: Employees and Managers

Let’s consider an example of a company where we have different types of employees. We can create a base class called Employee, and then create a subclass called Manager that inherits from Employee. The Manager class will have additional responsibilities or attributes, such as managing a team.

Base Class: Employee

class Employee {
    String name;
    int id;
    double salary;

    public Employee(String name, int id, double salary) {
        this.name = name;
        this.id = id;
        this.salary = salary;
    }

    public void displayDetails() {
        System.out.println("Employee ID: " + id);
        System.out.println("Name: " + name);
        System.out.println("Salary: $" + salary);
    }
}

Subclass: Manager

class Manager extends Employee {
    String department;

    public Manager(String name, int id, double salary, String department) {
        super(name, id, salary);  // Call to the constructor of the base class (Employee)
        this.department = department;
    }

    public void displayDetails() {
        super.displayDetails();  // Call the method from the base class to display common details
        System.out.println("Department: " + department);
    }
}

Main Class to Test Inheritance

public class Company {
    public static void main(String[] args) {
        Employee emp = new Employee("Rahul Sharma", 101, 50000);
        emp.displayDetails();
        
        System.out.println();

        Manager mgr = new Manager("Priya Verma", 102, 75000, "IT");
        mgr.displayDetails();
    }
}

Output

Employee ID: 101
Name: Rahul Sharma
Salary: $50000.0

Employee ID: 102
Name: Priya Verma
Salary: $75000.0
Department: IT

Explanation

  1. Inheritance: The Manager class inherits from the Employee class using the extends keyword. This means Manager has access to the fields (name, id, salary) and methods (displayDetails()) of the Employee class.
  2. Constructor Chaining: In the Manager class, the constructor calls super(name, id, salary) to invoke the constructor of the Employee class, ensuring that the name, id, and salary fields are properly initialized.
  3. Method Overriding: The displayDetails() method in the Manager class overrides the displayDetails() method in the Employee class. However, it still calls super.displayDetails() to reuse the code for displaying common details (ID, name, salary) and then adds the specific detail for Manager, which is the department.
  4. Output: When the displayDetails() method is called on an Employee object, only the employee’s ID, name, and salary are displayed. When called on a Manager object, the method displays the same details as for Employee, plus the department information, showing how inheritance and method overriding work in Java.

This example demonstrates how inheritance allows for code reuse and extension, enabling subclasses to build upon the base class’s functionality.

8. Conclusion

Inheritance in Java is a powerful feature that promotes code reusability and hierarchical class organization. By understanding how to implement and use inheritance, including the use of the super keyword and method overriding, you can create more flexible and maintainable code. Inheritance allows for building complex class structures that model real-world relationships effectively.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top