Inheritance and Polymorphism

Dive deeper into inheritance, its benefits, and different types (single, multiple, multilevel). Understand polymorphism (method overriding and overloading) and its applications.


Single Inheritance in Java

Explanation of Single Inheritance

Single inheritance is a fundamental concept in object-oriented programming (OOP) where a class can inherit from only one parent class. This means a child class (also called a subclass or derived class) can inherit the properties and behaviors (fields and methods) of a single parent class (also called a superclass or base class). It promotes code reusability and establishes an "is-a" relationship between the parent and child classes.

Key aspects of Single Inheritance:

  • Code Reusability: The child class automatically inherits the properties and methods of the parent class, reducing the need to rewrite the same code.
  • "Is-A" Relationship: Single inheritance implies an "is-a" relationship. For example, if we have a Vehicle class and a Car class inheriting from Vehicle, we can say that a Car "is a" Vehicle.
  • Simplified Hierarchy: Since a class can only inherit from one parent, it leads to a simpler and more manageable class hierarchy.

Implementation of Single Inheritance with Code Examples

Here's a Java code example demonstrating single inheritance:

Example: Animal and Dog Classes

 // Parent class (Superclass)
class Animal {
    String name;

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

    public void eat() {
        System.out.println(name + " is eating.");
    }

    public void sleep() {
        System.out.println(name + " is sleeping.");
    }

    public String getName() {
        return name;
    }
}

// Child class (Subclass) inheriting from Animal
class Dog extends Animal {
    String breed;

    public Dog(String name, String breed) {
        // Call the constructor of the parent class
        super(name);
        this.breed = breed;
    }

    public void bark() {
        System.out.println(getName() + " (a " + breed + ") is barking.");
    }
}

public class Main {
    public static void main(String[] args) {
        // Create an instance of the Dog class
        Dog myDog = new Dog("Buddy", "Golden Retriever");

        // Access methods inherited from the Animal class
        myDog.eat();   // Output: Buddy is eating.
        myDog.sleep(); // Output: Buddy is sleeping.

        // Access the Dog class's own method
        myDog.bark();  // Output: Buddy (a Golden Retriever) is barking.

        // Access the inherited name field through the getName() method
        System.out.println("Dog's name: " + myDog.getName()); // Output: Dog's name: Buddy
    }
} 

Explanation:

  • The Animal class is the parent class (superclass). It has a name field, a constructor, and methods eat(), sleep(), and getName().
  • The Dog class is the child class (subclass). It uses the extends keyword to inherit from the Animal class.
  • The Dog class has its own breed field and a bark() method.
  • The Dog constructor uses super(name) to call the constructor of the parent class (Animal) and initialize the name field. This is crucial to properly initialize the inherited fields.
  • In the Main class, we create a Dog object. We can then access the methods inherited from Animal (eat(), sleep()) as well as the Dog's own method (bark()). We can also access the inherited name using the getName() method defined in the parent class.

Key takeaways from the example:

  • The extends keyword is used to establish the inheritance relationship.
  • The super() keyword is used to call the constructor of the parent class, ensuring proper initialization of inherited fields.
  • The child class inherits all accessible members (fields and methods) of the parent class. Note that private members of the parent class are not directly accessible in the child class, though their values can be indirectly accessed through `public` or `protected` getter/setter methods if they exist.

This example demonstrates how single inheritance allows the Dog class to reuse the code defined in the Animal class, making the code more organized and maintainable. It also enforces the "is-a" relationship: a Dog is an Animal.