Inheritance
java inheritance extends super override final class diamond problem single multilevel hierarchical IS-A composition method overriding
Introduction
In the previous lessons, you learned about Classes, Objects, Constructors, Methods, and Encapsulation.
Imagine you're developing a Human Resource (HR) Management System.
Without inheritance, you might write:
class Manager {String name;int age;void login() {System.out.println("Login");}}class Developer {String name;int age;void login() {System.out.println("Login");}}
Notice that the name, age, and login() code is duplicated.
As applications grow, duplicate code becomes difficult to maintain.
Java solves this problem using Inheritance, one of the four fundamental pillars of Object-Oriented Programming (OOP).
Inheritance allows one class to inherit the properties and behaviors of another class, promoting code reuse, extensibility, and maintainability.
Inheritance is extensively used in:
- Spring Boot
- Hibernate/JPA
- Android Development
- Java Collections Framework
- Enterprise Applications
- Microservices
- GUI Applications
In this lesson, you'll learn:
- What is Inheritance?
- Why Inheritance is Needed
- Parent and Child Classes
extendsKeyword- Types of Inheritance
- Method Overriding
superKeyword- Constructor Chaining
finalClass & Method- Object Relationship (IS-A)
- Memory Model
- Real-world Examples
- Best Practices
- Common Mistakes
- Hands-on Exercises
- Professional Interview Questions
What is Inheritance?
Inheritance is the mechanism by which one class acquires the properties and methods of another class.
The existing class is called the:
- Parent Class
- Superclass
- Base Class
The new class is called the:
- Child Class
- Subclass
- Derived Class
Example:
Animal↓Dog
The Dog class automatically inherits the members of the Animal class.
Why Inheritance?
Suppose every employee has:
- Employee ID
- Name
- Login()
- Logout()
Instead of rewriting them:
ManagerDeveloperTester
All inherit from:
Employee
Benefits:
- Code Reusability
- Less Duplication
- Easier Maintenance
- Better Extensibility
- Cleaner Design
- Supports Polymorphism
The extends Keyword
Java uses the extends keyword to create inheritance.
class Animal {void eat() {System.out.println("Eating...");}}class Dog extends Animal {void bark() {System.out.println("Barking...");}}
Using it:
Dog dog = new Dog();dog.eat();dog.bark();
Output:
Eating...Barking...
Parent and Child Relationship
Parent (Superclass)↓Child (Subclass)
The child class automatically inherits:
- Non-private fields
- Non-private methods
Private members remain accessible only within the parent class.
IS-A Relationship
Inheritance represents an IS-A relationship.
Examples:
Dog IS-A AnimalCar IS-A VehicleSavingsAccount IS-A BankAccount
If an "IS-A" relationship does not exist, inheritance is usually not appropriate.
Types of Inheritance in Java
Java supports:
Single Inheritance
Animal↓Dog
Multilevel Inheritance
Animal↓Dog↓Puppy
Hierarchical Inheritance
Animal/ \Dog Cat
Multiple Inheritance
Java does not support multiple inheritance with classes.
Example (Not Allowed):
class A {}class B {}// Compilation Errorclass C extends A, B {}
Reason:
It can create ambiguity, commonly known as the Diamond Problem.
Java solves this using Interfaces, which you'll learn later.
Method Overriding
A child class can provide its own implementation of a parent method.
Example:
class Animal {void sound() {System.out.println("Animal Sound");}}class Dog extends Animal {@Overridevoid sound() {System.out.println("Dog Barks");}}
Calling:
Dog dog = new Dog();dog.sound();
Output:
Dog Barks
The @Override annotation instructs the compiler to verify that a parent method is actually being overridden.
The super Keyword
The super keyword refers to the parent class.
Calling a parent method:
class Animal {void eat() {System.out.println("Animal Eating");}}class Dog extends Animal {void eat() {super.eat();System.out.println("Dog Eating");}}
Output:
Animal EatingDog Eating
Accessing Parent Variables
class Animal {String name = "Animal";}class Dog extends Animal {String name = "Dog";void printName() {System.out.println(super.name);System.out.println(this.name);}}
Output:
AnimalDog
Constructor Chaining
Whenever a child object is created, the parent constructor executes first.
Example:
class Animal {Animal() {System.out.println("Animal Constructor");}}class Dog extends Animal {Dog() {System.out.println("Dog Constructor");}}
Creating object:
Dog dog = new Dog();
Output:
Animal ConstructorDog Constructor
Java automatically inserts super() as the first statement if it is not specified.
Calling Parameterized Parent Constructor
class Animal {Animal(String type) {System.out.println(type);}}class Dog extends Animal {Dog() {super("Mammal");}}
Output:
Mammal
final Class
A final class cannot be inherited.
Example:
final class Utility {}
This is invalid:
class Demo extends Utility {}
Compilation Error.
Example from Java:
String
String is final, preventing subclassing.
final Method
A final method cannot be overridden.
Example:
class Animal {final void breathe() {System.out.println("Breathing");}}
Trying to override breathe() results in a compilation error.
Memory Representation
Dog dog = new Dog();
Memory:
Stackdog↓Heap+----------------------+| Animal Fields || Dog Fields |+----------------------+
A child object contains both inherited parent state and its own state.
Real-World Example: Banking Application
class Account {void deposit() {System.out.println("Depositing...");}}class SavingsAccount extends Account {void calculateInterest() {System.out.println("Calculating Interest...");}}
Using it:
SavingsAccount account = new SavingsAccount();account.deposit();account.calculateInterest();
Output:
Depositing...Calculating Interest...
Real-World Example: Vehicle System
class Vehicle {void start() {System.out.println("Vehicle Started");}}class Car extends Vehicle {void openSunroof() {System.out.println("Opening Sunroof");}}
Best Practices
Use Inheritance Only for an IS-A Relationship
Good:
Dog IS-A Animal
Bad:
Engine IS-A Car
An engine is part of a car (HAS-A relationship), so composition is more appropriate.
Keep Parent Classes Generic
Parent classes should contain common behavior shared by multiple child classes.
Avoid Deep Inheritance Hierarchies
Very deep inheritance trees make code harder to understand and maintain.
Use @Override
Always annotate overridden methods with @Override to catch mistakes at compile time.
Prefer Composition When Appropriate
If classes don't have a true IS-A relationship, favor composition over inheritance.
Common Mistakes
Using Inheritance for Code Reuse Only
Inheritance should model a genuine IS-A relationship, not just avoid duplicate code.
Forgetting to Call super(...)
When a parent class has only parameterized constructors, the child constructor must explicitly call super(...).
Overriding final Methods
A final method cannot be overridden.
Trying Multiple Inheritance with Classes
Java allows extending only one class. Multiple inheritance is achieved using interfaces.
Confusing Overloading and Overriding
- Overloading → Same class, different parameters.
- Overriding → Child class redefines parent method with the same signature.
Hands-on Exercise
Create a Java program that:
- Creates a
Personclass with common fields (name,age) and methods (displayInfo()). - Creates
StudentandTeacherclasses that extendPerson. - Overrides
displayInfo()in both child classes. - Uses
superto invoke the parent implementation. - Demonstrates constructor chaining with default and parameterized constructors.
- Creates a
finalutility class and observes the compilation restriction. - Prints object details to verify inherited and overridden behavior.
Summary
Inheritance enables one class to reuse and extend the functionality of another class. It promotes code reuse, maintainability, and scalability while modeling real-world IS-A relationships. Features such as method overriding, the super keyword, constructor chaining, and final help developers build robust and extensible object-oriented systems.
Key Takeaways
- Inheritance allows one class to inherit another class's properties and methods.
- Java uses the
extendskeyword to implement inheritance. - Inheritance models an IS-A relationship.
- Java supports Single, Multilevel, and Hierarchical inheritance for classes.
- Java does not support multiple inheritance with classes.
- Child classes can override parent methods.
- The
superkeyword accesses parent constructors, fields, and methods. - Parent constructors execute before child constructors.
finalclasses cannot be extended, andfinalmethods cannot be overridden.- Prefer composition when an IS-A relationship does not exist.
Professional Interview Questions
1What is Inheritance in Java?
Professional Answer
Inheritance is an Object-Oriented Programming mechanism that allows a class to acquire the properties and behaviors of another class. It promotes code reuse, supports hierarchical relationships, and enables runtime polymorphism through method overriding.
Follow-up Questions
- Which keyword is used to implement inheritance?
- What is the difference between inheritance and composition?
Interview Tip: Mention that inheritance should represent a true IS-A relationship rather than being used only to eliminate duplicate code.
2Why doesn't Java support Multiple Inheritance with Classes?
Professional Answer
Java does not support multiple inheritance with classes because it can lead to ambiguity when two parent classes define methods with the same signature. This ambiguity is known as the Diamond Problem. Java avoids this complexity by allowing a class to extend only one class while supporting multiple inheritance of type through interfaces.
Follow-up Questions
- What is the Diamond Problem?
- How do interfaces solve this limitation?
Interview Tip: Remember: One Class → One Parent Class, One Class → Multiple Interfaces.
3What is the difference between Method Overloading and Method Overriding?
Professional Answer
Method overloading occurs within the same class when multiple methods share the same name but have different parameter lists. It is resolved at compile time (compile-time polymorphism). Method overriding occurs when a child class provides its own implementation of a parent class method with the same signature. It is resolved at runtime (runtime polymorphism).
Follow-up Questions
- Can static methods be overridden?
- Why is the @Override annotation recommended?
Interview Tip: Overloading = Same Class + Different Parameters. Overriding = Parent & Child + Same Signature.
Next Lesson: Java Polymorphism — compile-time vs runtime polymorphism, upcasting and downcasting, dynamic method dispatch, and real-world enterprise examples.