Inheritance and the super Keyword in Java


Table of Contents

  1. Introduction to Inheritance
  2. Types of Inheritance in Java
  3. The extends Keyword
  4. Why Use Inheritance?
  5. The super Keyword
    • Accessing Parent Class Members
    • Invoking Parent Class Constructor
  6. Method Overriding in Inheritance
  7. Inheritance with Constructors
  8. Hierarchical vs Multilevel Inheritance
  9. Composition vs Inheritance
  10. Common Pitfalls and Best Practices
  11. Summary

1. Introduction to Inheritance

Inheritance is one of the four fundamental principles of Object-Oriented Programming (OOP), alongside encapsulation, abstraction, and polymorphism. It allows a class (child or subclass) to inherit fields and methods from another class (parent or superclass), promoting code reuse and establishing a logical hierarchy between classes.

For example, if we have a class Vehicle, we can create child classes like Car, Bike, and Truck that inherit the general behavior of Vehicle.


2. Types of Inheritance in Java

Java supports the following types of inheritance:

  • Single Inheritance: One class inherits from another.
  • Multilevel Inheritance: A class inherits from a derived class.
  • Hierarchical Inheritance: Multiple classes inherit from a single parent class.
Java does not support multiple inheritance with classes to avoid ambiguity, but this can be achieved using interfaces.

3. The extends Keyword

To inherit from a class in Java, the extends keyword is used.

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

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

Here, Dog inherits the method eat() from Animal.


4. Why Use Inheritance?

  • Code Reusability: Write common logic once and reuse it across subclasses.
  • Logical Hierarchy: Reflect real-world relationships (e.g., Dog is-an Animal).
  • Method Overriding: Customize behavior in child classes.
  • Maintenance: Easier to manage code in one place.

5. The super Keyword

The super keyword refers to the immediate parent class and is used to:

  • Access parent class methods and variables
  • Call parent class constructor

a. Accessing Parent Class Members

class Animal {
String sound = "Generic Sound";

void displaySound() {
System.out.println("Animal Sound: " + sound);
}
}

class Cat extends Animal {
String sound = "Meow";

void displaySound() {
System.out.println("Cat Sound: " + sound);
System.out.println("Animal Sound: " + super.sound); // Accessing parent member
}
}

b. Invoking Parent Class Constructor

super() is used to call the constructor of the parent class and must be the first statement in the subclass constructor.

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

class Dog extends Animal {
Dog() {
super(); // Calls Animal constructor
System.out.println("Dog constructor called");
}
}

This is especially useful when the parent class has a parameterized constructor.


6. Method Overriding in Inheritance

When a child class defines a method with the same signature as one in its parent class, it overrides the parent method.

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

class Lion extends Animal {
@Override
void sound() {
System.out.println("Lion roars");
}
}

Using super to Access Overridden Method

class Lion extends Animal {
@Override
void sound() {
super.sound(); // Calls parent class method
System.out.println("Lion roars");
}
}

7. Inheritance with Constructors

Constructors are not inherited, but they can be called using super().

class Animal {
Animal(String name) {
System.out.println("Animal name: " + name);
}
}

class Elephant extends Animal {
Elephant() {
super("Elephant"); // Calls parent constructor
System.out.println("Elephant constructor done");
}
}

If the parent class does not have a default (no-argument) constructor, the child class must explicitly call a parameterized one using super.


8. Hierarchical vs Multilevel Inheritance

Hierarchical Inheritance

class Animal { }

class Cat extends Animal { }

class Dog extends Animal { }

class Cow extends Animal { }

Multiple classes share a single base class.

Multilevel Inheritance

class Animal { }

class Mammal extends Animal { }

class Human extends Mammal { }

Inheritance in a chain format—each level builds on the previous one.


9. Composition vs Inheritance

Sometimes, composition is preferred over inheritance, especially when the relationship is has-a rather than is-a.

  • Inheritance: Car is-a Vehicle
  • Composition: Car has-an Engine

Composition increases flexibility, avoids tight coupling, and enhances code maintainability.


10. Common Pitfalls and Best Practices

Pitfalls

  • Overusing inheritance can make the code rigid and hard to refactor.
  • Failing to use super() when necessary in constructors.
  • Forgetting that private members are not accessible in subclasses.
  • Confusing method overriding with method overloading.

Best Practices

  • Prefer composition over inheritance unless is-a clearly applies.
  • Always mark overridden methods with @Override for clarity and compile-time checks.
  • Avoid deep inheritance hierarchies; use interfaces where applicable.
  • Ensure constructors properly invoke parent constructors for initialization.

11. Summary

Inheritance in Java is a cornerstone of OOP that enables efficient code reuse and logical relationships between classes. The super keyword enhances control over parent-child interactions, whether it’s accessing variables, methods, or constructors. When used wisely, inheritance can lead to elegant and maintainable designs, but it must be applied with clear intent and good understanding of when alternatives like composition are better suited.