Inheritance in Java
Learn Inheritance in Java in detail, including parent and child classes, extends keyword, IS-A relationship, method inheritance, constructor chaining, super keyword, method overriding, inheritance types, access control, and best practices.
Introduction
Inheritance is one of the fundamental principles of Object-Oriented Programming. It allows a new class to reuse, extend, and specialize the behavior of an existing class.
class Animal {
void eat() {
System.out.println(
"Animal is eating"
);
}
}
class Dog extends Animal {
void bark() {
System.out.println(
"Dog is barking"
);
}
}Dog dog = new Dog();
dog.eat();
dog.bark();The Dog class defines bark() itself and inherits the accessible eat() method from Animal.
- What inheritance is.
- Why inheritance is useful.
- What parent and child classes are.
- How the extends keyword works.
- What the IS-A relationship means.
- Which class members are inherited.
- How access modifiers affect inheritance.
- How constructors work with inheritance.
- What constructor execution order is.
- How the super keyword works.
- How to call parent constructors.
- How to call parent methods.
- How constructor chaining works.
- What method overriding is.
- Rules of method overriding.
- How the @Override annotation works.
- What field hiding is.
- What static method hiding is.
- What single inheritance is.
- What multilevel inheritance is.
- What hierarchical inheritance is.
- Why Java does not support multiple inheritance of classes.
- How every class inherits from Object.
- What upcasting is.
- What downcasting is.
- How instanceof works.
- How final affects inheritance.
- How abstract classes use inheritance.
- How inheritance works with encapsulation.
- The difference between inheritance and composition.
- When inheritance should be used.
- When inheritance should be avoided.
What is Inheritance?
Inheritance is the mechanism by which one class acquires accessible fields and methods from another class. The new class can reuse existing behavior and add or specialize its own behavior.
PARENT CLASS
Animal
eat()
sleep()
│
│ inherited by
▼
CHILD CLASS
Dog
eat() inherited
sleep() inherited
bark() own method- Parent class is also called superclass or base class.
- Child class is also called subclass or derived class.
- The child class extends the parent class.
- The child class can add new members.
- The child class can override inherited methods.
Why Use Inheritance?
Code Reuse
Common behavior can be defined once in a parent class and reused by child classes.
Specialization
Child classes can add behavior specific to their own purpose.
Method Overriding
Child classes can provide specialized implementations of inherited methods.
Class Hierarchies
Related classes can be organized into meaningful parent-child structures.
Polymorphism
Parent references can work with objects of different child classes.
Maintainability
Shared behavior can be maintained in one common location.
Real-World Analogy
Think of inheritance as specialization. A car is a vehicle. A motorcycle is also a vehicle. Both share general vehicle behavior but also have their own specialized features.
VEHICLE
start()
stop()
move()
/ \
/ \
▼ ▼
CAR MOTORCYCLE
openTrunk() kickStart()
CAR IS-A VEHICLE
MOTORCYCLE IS-A VEHICLEParent and Child Classes
class Animal {
void eat() {
System.out.println(
"Eating"
);
}
}class Dog extends Animal {
void bark() {
System.out.println(
"Barking"
);
}
}Animal
Parent Class
Superclass
Base Class
Dog
Child Class
Subclass
Derived ClassThe extends Keyword
The extends keyword creates an inheritance relationship between two classes.
class ChildClass
extends ParentClass {
// Additional fields
// Additional methods
}class Vehicle {
}
class Car extends Vehicle {
}Basic Inheritance Example
public class Animal {
public void eat() {
System.out.println(
"Animal is eating"
);
}
public void sleep() {
System.out.println(
"Animal is sleeping"
);
}
}public class Dog
extends Animal {
public void bark() {
System.out.println(
"Dog is barking"
);
}
}public class Main {
public static void main(
String[] args
) {
Dog dog = new Dog();
dog.eat();
dog.sleep();
dog.bark();
}
}Animal is eating
Animal is sleeping
Dog is barkingHow Inheritance Works
DOG OBJECT
│
├── Own Members
│
│ bark()
│
└── Inherited Accessible Members
eat()
sleep()
dog.eat()
│
▼
Method inherited from Animal
dog.bark()
│
▼
Method declared in DogIS-A Relationship
Inheritance should represent an IS-A relationship. If Child extends Parent, the child should logically be a specialized type of the parent.
Dog IS-A Animal
Car IS-A Vehicle
Manager IS-A Employee
SavingsAccount IS-A BankAccount
Circle IS-A ShapeEngine IS-A Car
Incorrect
Engine HAS-A Car?
Also incorrect
Car HAS-A Engine
Correct relationship
Use composition- Use inheritance for a genuine IS-A relationship.
- Do not use inheritance only to reuse code.
- Use composition for HAS-A relationships.
- A Car has an Engine, so Engine should not extend Car.
Inherited Members
A child class inherits accessible members from its parent according to Java access-control rules.
class Parent {
public int publicValue;
protected int protectedValue;
int packageValue;
private int privateValue;
public void publicMethod() {
}
protected void protectedMethod() {
}
}- Public members are accessible according to normal public access.
- Protected members support subclass access.
- Package-private members are accessible when package rules allow it.
- Private members are not directly accessible in the child class.
- Constructors are not inherited.
What is Not Inherited?
NOT DIRECTLY INHERITED
Constructors
NOT DIRECTLY ACCESSIBLE
Private parent members
SPECIAL CASES
Static methods are hidden,
not overridden
Fields can be hidden,
not overriddenAccess Modifiers in Inheritance
MODIFIER CHILD ACCESS
public Yes
protected Yes
package-private Same package
private No direct accessPublic Members
class Parent {
public void display() {
System.out.println(
"Parent method"
);
}
}
class Child extends Parent {
void test() {
display();
}
}Protected Members
class Employee {
protected double salary;
}
class Manager extends Employee {
void showSalary() {
System.out.println(
salary
);
}
}- Protected members are more exposed than private members.
- Protected mutable fields can weaken encapsulation.
- Private fields with controlled protected methods are often safer.
Package-Private Members
A member with no explicit access modifier is package-private. A child class can access it only when normal package access rules allow it.
class Parent {
int value = 10;
}
class Child extends Parent {
void display() {
System.out.println(value);
}
}Private Members
class Parent {
private int value = 10;
public int getValue() {
return value;
}
}
class Child extends Parent {
void display() {
System.out.println(
getValue()
);
}
}The child class cannot directly access value, but it can use an accessible method provided by the parent.
Constructors and Inheritance
Constructors are not inherited. However, creating a child object requires initialization of the parent part of that object, so a parent constructor executes before the child constructor.
class Parent {
Parent() {
System.out.println(
"Parent constructor"
);
}
}
class Child extends Parent {
Child() {
System.out.println(
"Child constructor"
);
}
}Child child = new Child();Parent constructor
Child constructorConstructor Execution Order
new Child()
│
▼
Parent Constructor
│
▼
Child Constructor
│
▼
Object ReadyIn a deeper hierarchy, constructors execute from the highest parent class down to the most specific child class.
The super Keyword
The super keyword refers to the parent-class part of the current object.
- Call a parent constructor.
- Call a parent method.
- Access a hidden parent field.
Calling Parent Constructor
class Employee {
private String name;
Employee(String name) {
this.name = name;
}
public String getName() {
return name;
}
}class Manager extends Employee {
private String department;
Manager(
String name,
String department
) {
super(name);
this.department =
department;
}
}- A call to super() must be the first statement in a constructor.
- If no constructor call is written, Java attempts to insert super().
- The parent constructor must exist and be accessible.
Calling Parent Methods
class Animal {
void sound() {
System.out.println(
"Animal sound"
);
}
}
class Dog extends Animal {
@Override
void sound() {
super.sound();
System.out.println(
"Dog barks"
);
}
}Accessing Parent Fields
class Parent {
int value = 10;
}
class Child extends Parent {
int value = 20;
void display() {
System.out.println(value);
System.out.println(
super.value
);
}
}20
10Constructor Chaining
class A {
A() {
System.out.println("A");
}
}
class B extends A {
B() {
System.out.println("B");
}
}
class C extends B {
C() {
System.out.println("C");
}
}C object = new C();A
B
CDefault Constructor Problem
class Parent {
Parent(int value) {
}
}
class Child extends Parent {
Child() {
super(10);
}
}- The parent has no no-argument constructor.
- Java cannot successfully insert super().
- The child must explicitly call an available parent constructor.
Method Inheritance
class Vehicle {
void start() {
System.out.println(
"Vehicle started"
);
}
}
class Car extends Vehicle {
}
Car car = new Car();
car.start();Method Overriding
Method overriding occurs when a child class provides its own implementation of an inherited instance method.
class Animal {
void sound() {
System.out.println(
"Animal makes sound"
);
}
}
class Dog extends Animal {
@Override
void sound() {
System.out.println(
"Dog barks"
);
}
}Rules of Method Overriding
- The child method must have the same method name.
- The child method must have the same parameter list.
- The return type must be compatible.
- The child method cannot reduce access visibility.
- Private methods are not overridden.
- Static methods are hidden rather than overridden.
- Final methods cannot be overridden.
- The overriding method may use a covariant return type.
- Checked exception rules must be respected.
@Override Annotation
@Override
public void display() {
System.out.println(
"Child implementation"
);
}- The compiler verifies that overriding actually occurs.
- Typing mistakes are detected.
- Code intent becomes clearer.
- Maintenance becomes safer.
Calling an Overridden Parent Method
class Employee {
void work() {
System.out.println(
"Employee is working"
);
}
}
class Manager extends Employee {
@Override
void work() {
super.work();
System.out.println(
"Manager is managing"
);
}
}Field Hiding
Fields are not overridden. When a child declares a field with the same name as a parent field, the child field hides the parent field.
class Parent {
String name = "Parent";
}
class Child extends Parent {
String name = "Child";
}Method Overriding vs Field Hiding
METHOD OVERRIDING
Applies to instance methods
Resolved using actual object type
Supports runtime polymorphism
FIELD HIDING
Applies to fields
Resolved using reference type
Does not provide polymorphic behaviorStatic Method Hiding
class Parent {
static void display() {
System.out.println("Parent");
}
}
class Child extends Parent {
static void display() {
System.out.println("Child");
}
}Static methods belong to classes and are hidden rather than overridden.
Single Inheritance
Animal
│
▼
Dogclass Animal {
}
class Dog extends Animal {
}Multilevel Inheritance
Animal
│
▼
Mammal
│
▼
Dogclass Animal {
}
class Mammal extends Animal {
}
class Dog extends Mammal {
}Hierarchical Inheritance
Animal
/ | \
/ | \
▼ ▼ ▼
Dog Cat Birdclass Animal {
}
class Dog extends Animal {
}
class Cat extends Animal {
}
class Bird extends Animal {
}Multiple Inheritance
Java does not allow a class to directly extend multiple classes.
class Child
extends ParentA, ParentB {
}
// Compilation error ParentA
method()
/ \
/ \
▼ ▼
ParentB ParentC
method() method()
\ /
\ /
▼
Child
Which implementation
should Child inherit?- A class can extend only one class.
- A class can implement multiple interfaces.
- Interfaces provide controlled multiple-type inheritance.
Hybrid Inheritance
Hybrid inheritance combines multiple inheritance patterns. Java does not support every hybrid form through classes alone, but combinations can be created using classes and interfaces.
The Object Class
Every Java class directly or indirectly extends java.lang.Object.
class Student {
}class Student extends Object {
}- toString()
- equals()
- hashCode()
- getClass()
Upcasting
Upcasting stores a child object in a parent-type reference. It is automatic and safe.
Dog dog = new Dog();
Animal animal = dog;Animal animal =
new Dog();Downcasting
Downcasting converts a parent reference back to a more specific child reference. It requires an explicit cast and can fail at runtime if the object is not actually of that child type.
Animal animal =
new Dog();
Dog dog =
(Dog) animal;Animal animal =
new Animal();
Dog dog =
(Dog) animal;
// ClassCastExceptioninstanceof Operator
if (animal instanceof Dog) {
Dog dog =
(Dog) animal;
dog.bark();
}Pattern Matching with instanceof
if (animal instanceof Dog dog) {
dog.bark();
}Pattern matching combines the type check and variable creation into one operation.
final Classes
final class SecurityManager {
}
// Not allowed
class CustomManager
extends SecurityManager {
}A final class cannot be extended.
final Methods
class Parent {
final void display() {
System.out.println(
"Fixed behavior"
);
}
}A final method can be inherited but cannot be overridden.
Abstract Classes and Inheritance
abstract class Shape {
abstract double area();
void display() {
System.out.println(
"This is a shape"
);
}
}class Circle extends Shape {
private double radius;
Circle(double radius) {
this.radius = radius;
}
@Override
double area() {
return Math.PI
* radius
* radius;
}
}Inheritance and Encapsulation
class Employee {
private double salary;
public double getSalary() {
return salary;
}
protected void increaseSalary(
double amount
) {
if (amount > 0) {
salary += amount;
}
}
}
class Manager extends Employee {
void applyBonus() {
increaseSalary(5000);
}
}The child class extends behavior without directly accessing the private salary field.
Inheritance vs Composition
INHERITANCE
IS-A relationship
Car IS-A Vehicle
class Car extends Vehicle
COMPOSITION
HAS-A relationship
Car HAS-A Engine
class Car {
private Engine engine;
}- Use inheritance for genuine specialization.
- Use composition when one object contains or uses another.
- Do not force inheritance only to reuse implementation.
- Composition often provides greater flexibility.
When to Use Inheritance
- When a genuine IS-A relationship exists.
- When the child is a true specialization of the parent.
- When inherited behavior is logically valid for every child.
- When polymorphism is required.
- When the parent class provides a stable abstraction.
- When child objects can safely be used wherever parent objects are expected.
When to Avoid Inheritance
- When the relationship is HAS-A rather than IS-A.
- When inheritance is used only to reuse code.
- When the child must disable important parent behavior.
- When the parent implementation changes frequently.
- When deep inheritance hierarchies become difficult to understand.
- When composition provides a simpler and more flexible design.
Vehicle Example
public class Vehicle {
private final String brand;
private int speed;
public Vehicle(String brand) {
this.brand = brand;
}
public String getBrand() {
return brand;
}
public int getSpeed() {
return speed;
}
protected void setSpeed(int speed) {
if (speed >= 0) {
this.speed = speed;
}
}
public void start() {
System.out.println(
brand + " started"
);
}
public void stop() {
speed = 0;
System.out.println(
brand + " stopped"
);
}
}public class Car extends Vehicle {
private final int doors;
public Car(
String brand,
int doors
) {
super(brand);
this.doors = doors;
}
public int getDoors() {
return doors;
}
public void accelerate() {
setSpeed(
getSpeed() + 10
);
}
}Employee Example
public class Employee {
private final int id;
private String name;
private double salary;
public Employee(
int id,
String name,
double salary
) {
this.id = id;
this.name = name;
this.salary = salary;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
public double getSalary() {
return salary;
}
public void work() {
System.out.println(
name + " is working"
);
}
}public class Manager
extends Employee {
private String department;
public Manager(
int id,
String name,
double salary,
String department
) {
super(
id,
name,
salary
);
this.department =
department;
}
@Override
public void work() {
System.out.println(
getName()
+ " is managing "
+ department
);
}
}Bank Account Example
public class BankAccount {
private double balance;
public void deposit(double amount) {
if (amount > 0) {
balance += amount;
}
}
public boolean withdraw(
double amount
) {
if (amount <= 0 ||
amount > balance) {
return false;
}
balance -= amount;
return true;
}
public double getBalance() {
return balance;
}
}public class SavingsAccount
extends BankAccount {
private double interestRate;
public SavingsAccount(
double interestRate
) {
this.interestRate =
interestRate;
}
public void addInterest() {
double interest =
getBalance()
* interestRate
/ 100;
deposit(interest);
}
}Shape Example
public abstract class Shape {
public abstract double area();
public void displayArea() {
System.out.println(
"Area: " + area()
);
}
}public class Rectangle
extends Shape {
private double width;
private double height;
public Rectangle(
double width,
double height
) {
this.width = width;
this.height = height;
}
@Override
public double area() {
return width * height;
}
}Common Inheritance Errors
INHERITANCE ERRORS
├── Using Inheritance Without IS-A Relationship
├── Using Inheritance Only for Code Reuse
├── Confusing IS-A and HAS-A
├── Trying to Extend Multiple Classes
├── Forgetting extends Keyword
├── Trying to Access Private Parent Fields Directly
├── Assuming Constructors are Inherited
├── Forgetting Parent Constructor Execution
├── Forgetting super() Rules
├── Calling super() After Another Statement
├── Missing Required Parent Constructor Call
├── Assuming Child Constructor Runs First
├── Confusing this() and super()
├── Trying to Use Both this() and super() Explicitly First
├── Incorrect Method Signature While Overriding
├── Forgetting @Override
├── Reducing Method Visibility
├── Trying to Override final Methods
├── Trying to Override Private Methods
├── Treating Static Method Hiding as Overriding
├── Treating Field Hiding as Overriding
├── Confusing Reference Type and Object Type
├── Unsafe Downcasting
├── Ignoring ClassCastException
├── Unnecessary instanceof Checks
├── Creating Deep Inheritance Hierarchies
├── Exposing Protected Mutable Fields
├── Breaking Parent Class Invariants
├── Overriding Methods Incorrectly
├── Calling Overridable Methods from Constructors
├── Creating Fragile Parent-Child Coupling
├── Violating the IS-A Relationship
├── Child Class Disabling Parent Behavior
├── Child Class Throwing UnsupportedOperationException for Parent Operations
├── Using Inheritance Instead of Composition
├── Creating God Parent Classes
├── Putting Unrelated Behavior in Base Classes
├── Duplicating Parent Logic in Child Classes
├── Forgetting super.method()
├── Overusing super
├── Depending on Parent Implementation Details
├── Breaking Encapsulation Through protected Fields
├── Assuming final Field Prevents Inheritance
├── Assuming final Class Methods Cannot Be Used
├── Forgetting Every Class Extends Object
├── Incorrect equals() in Inheritance Hierarchies
├── Incorrect hashCode() with Inheritance
├── Poor toString() Overrides
├── Overcomplicated Type Hierarchies
├── Excessive Downcasting
├── Using Type Checks Instead of Polymorphism
├── Creating Circular Design Dependencies
├── Confusing Inheritance with Object Containment
└── Ignoring Composition as an AlternativeBest Practices
- Use inheritance only for genuine IS-A relationships.
- Ensure the child is a true specialization of the parent.
- Do not use inheritance only to avoid code duplication.
- Prefer composition for HAS-A relationships.
- Keep inheritance hierarchies shallow.
- Design parent classes carefully.
- Keep parent class responsibilities focused.
- Protect parent state with encapsulation.
- Prefer private fields over protected mutable fields.
- Provide controlled protected methods when subclasses need extension points.
- Use @Override whenever overriding methods.
- Keep overriding behavior compatible with parent expectations.
- Do not reduce method visibility.
- Use super() explicitly when parent constructor arguments are required.
- Understand constructor execution order.
- Do not call overridable methods from constructors unless the design is carefully controlled.
- Use super.method() only when parent behavior should remain part of the child behavior.
- Avoid unnecessary field hiding.
- Avoid static method hiding when it creates confusion.
- Use upcasting to support polymorphism.
- Avoid unnecessary downcasting.
- Check types before unsafe casts.
- Use pattern matching with instanceof when appropriate.
- Use final classes when extension should not be allowed.
- Use final methods when specific behavior must remain unchanged.
- Use abstract classes for shared state and partial implementation.
- Keep public APIs stable.
- Avoid exposing parent implementation details.
- Do not let child classes break parent invariants.
- Use meaningful class hierarchies.
- Prefer behavior-based abstractions.
- Avoid deep chains such as A extends B extends C extends D extends E.
- Favor simple designs.
- Use interfaces when multiple capabilities are required.
- Remember that Java classes support only single inheritance.
- Remember that every class ultimately inherits from Object.
- Override equals(), hashCode(), and toString() carefully.
- Use polymorphism instead of repeated type checking where possible.
- Review whether every child can safely substitute for its parent.
- Use composition when behavior needs to change dynamically.
- Keep inheritance relationships stable.
- Document intended extension points.
- Avoid fragile dependencies on parent internals.
- Test overridden behavior.
- Test constructor chains.
- Design for maintainability rather than maximum reuse.
- Use inheritance as a modeling tool, not merely a shortcut.
Common Misconceptions
- Inheritance is not only for code reuse.
- A child class does not inherit constructors.
- A child class cannot directly access private parent fields.
- Private methods are not overridden.
- Static methods are not overridden.
- Fields are not overridden.
- A class cannot extend multiple classes.
- A child constructor does not execute before the parent constructor.
- super() is not optional when the required parent constructor needs arguments.
- super() must be the first constructor statement.
- this() and super() cannot both be explicit first constructor calls.
- Method overriding is different from method overloading.
- Upcasting does not create a new object.
- Downcasting does not change the actual object.
- A parent reference can refer to a child object.
- Reference type and object type are different concepts.
- final classes cannot be extended.
- final methods can be inherited but not overridden.
- Every Java class ultimately extends Object.
- Inheritance does not automatically provide good design.
- Deep inheritance hierarchies are not always better.
- Composition is often more flexible than inheritance.
- HAS-A relationships should not normally use inheritance.
- The extends keyword represents a type relationship.
- Protected fields are not always better than private fields.
- A child class should preserve valid parent behavior.
- Inheritance and polymorphism are related but different concepts.
- Interfaces and class inheritance are not the same.
- Multiple interface implementation is not multiple class inheritance.
- Good inheritance requires semantic compatibility.
Practice Exercises
- Create an Animal parent class.
- Add eat() and sleep() methods.
- Create Dog and Cat child classes.
- Add specialized methods.
- Test inherited behavior.
- Create a Vehicle parent class.
- Create Car and Motorcycle child classes.
- Use constructor chaining.
- Add specialized child behavior.
- Override a common method.
- Create an Employee parent class.
- Create Manager and Developer child classes.
- Keep salary private.
- Use protected behavior instead of protected fields.
- Override work().
- Create Animal.
- Create Mammal extending Animal.
- Create Dog extending Mammal.
- Add one method at each level.
- Call all accessible methods using a Dog object.
- Create three inheritance levels.
- Add constructors to every class.
- Print a message from every constructor.
- Create the lowest-level object.
- Observe execution order.
- Create a Shape parent class.
- Create Circle and Rectangle child classes.
- Override area().
- Use @Override.
- Call methods through parent references.
- Create Animal and Dog classes.
- Store Dog in an Animal reference.
- Call an overridden method.
- Check with instanceof.
- Safely downcast to Dog.
- Create Car and Engine classes.
- Use composition between Car and Engine.
- Explain why Engine should not extend Car.
- Create a valid inheritance relationship.
- Compare both designs.
Common Interview Questions
What is inheritance in Java?
Inheritance is the mechanism by which one class acquires accessible fields and methods from another class and can add or specialize behavior.
Which keyword is used for class inheritance?
The extends keyword is used.
What is a superclass?
A superclass is the parent class whose accessible members can be inherited by a child class.
What is a subclass?
A subclass is a child class that extends another class.
What is an IS-A relationship?
It is a relationship where a child class is logically a specialized type of its parent class.
Are constructors inherited?
No. Constructors are not inherited.
What is the super keyword?
The super keyword refers to the parent-class part of the current object.
Can Java classes support multiple inheritance?
No. A Java class can directly extend only one class.
What is method overriding?
Method overriding occurs when a child class provides its own implementation of an inherited instance method.
Can private methods be overridden?
No. Private methods are not visible to child classes and are not overridden.
Can static methods be overridden?
No. Static methods are hidden rather than overridden.
Can final methods be overridden?
No.
What is upcasting?
Upcasting stores a child object in a parent-type reference.
What is downcasting?
Downcasting converts a parent reference to a more specific child reference using an explicit cast.
What is the root class of Java?
java.lang.Object.
What is the difference between inheritance and composition?
Inheritance represents an IS-A relationship, while composition represents a HAS-A relationship.
Frequently Asked Questions
Can a child class have its own fields and methods?
Yes. A child class can add its own fields, constructors, and methods.
Can a child class override every parent method?
No. Private, static, and final methods do not participate in normal instance-method overriding.
Can a child access private parent fields?
Not directly. It must use accessible methods provided by the parent.
Does super create a parent object?
No. super refers to the parent-class part of the current object.
Can a class use both extends and implements?
Yes. A class can extend one class and implement one or more interfaces.
Should inheritance always be preferred for code reuse?
No. Composition is often more flexible and should be considered when the relationship is not a genuine IS-A relationship.
What should I learn after Inheritance?
The next lesson covers Polymorphism in Java.
Key Takeaways
- Inheritance is a fundamental Object-Oriented Programming principle.
- Inheritance allows a child class to reuse accessible parent behavior.
- The extends keyword creates class inheritance.
- The parent class is also called superclass or base class.
- The child class is also called subclass or derived class.
- Inheritance should represent an IS-A relationship.
- A Dog IS-A Animal.
- A Car IS-A Vehicle.
- Composition represents a HAS-A relationship.
- A Car HAS-A Engine.
- Public members can be inherited and accessed according to public rules.
- Protected members support subclass access.
- Package-private members depend on package access.
- Private members are not directly accessible in child classes.
- Constructors are not inherited.
- Parent constructors execute before child constructors.
- Constructor execution proceeds from parent to child.
- The super keyword refers to the parent part of the current object.
- super() calls a parent constructor.
- super.method() calls a parent method.
- super.field can access a hidden accessible parent field.
- A super constructor call must be the first constructor statement.
- Java inserts super() when possible.
- Method overriding provides specialized child behavior.
- Overriding requires a compatible method signature.
- The @Override annotation should be used.
- Private methods are not overridden.
- Static methods are hidden.
- Fields are hidden rather than overridden.
- Final methods cannot be overridden.
- Final classes cannot be extended.
- Single inheritance uses one parent and one child.
- Multilevel inheritance creates an inheritance chain.
- Hierarchical inheritance gives one parent multiple children.
- Java classes do not support multiple inheritance.
- A class can implement multiple interfaces.
- Every Java class ultimately extends Object.
- Upcasting is automatic.
- A parent reference can refer to a child object.
- Downcasting requires an explicit cast.
- Invalid downcasting can cause ClassCastException.
- instanceof can check an object type.
- Pattern matching simplifies instanceof checks.
- Abstract classes can provide shared behavior.
- Inheritance should preserve encapsulation.
- Private fields are usually safer than protected mutable fields.
- Composition is often more flexible than inheritance.
- Deep inheritance hierarchies should be avoided.
- Inheritance should not be used only for code reuse.
- Good inheritance requires a genuine type relationship.
- Child classes should remain valid substitutes for parent classes.
- Inheritance is a foundation for runtime polymorphism.
Summary
Inheritance allows one class to extend another class and reuse accessible state and behavior. The existing class is called the parent, superclass, or base class, while the extending class is called the child, subclass, or derived class.
Java uses the extends keyword for class inheritance. A class can extend only one class directly, although it can implement multiple interfaces.
Inheritance should model a genuine IS-A relationship. A Dog is an Animal and a Car is a Vehicle. HAS-A relationships, such as a Car having an Engine, are usually better represented through composition.
Constructors are not inherited, but parent constructors execute before child constructors. The super keyword can call parent constructors, invoke parent methods, and access hidden accessible parent fields.
Method overriding allows child classes to provide specialized implementations of inherited instance methods. The @Override annotation helps the compiler verify that overriding is intentional and correct.
Java supports single, multilevel, and hierarchical class inheritance. It does not support multiple inheritance of classes, helping avoid ambiguity such as the diamond problem.
Upcasting allows a child object to be referenced through a parent type and forms the foundation of runtime polymorphism. Downcasting converts a parent reference back to a more specific child reference and must be performed carefully.
Good inheritance design preserves encapsulation, keeps hierarchies shallow, uses genuine type relationships, and considers composition whenever a HAS-A relationship or greater flexibility is required.
- You understand what inheritance is.
- You understand why inheritance is useful.
- You understand parent and child classes.
- You can use the extends keyword.
- You understand the IS-A relationship.
- You understand inherited members.
- You understand access modifiers in inheritance.
- You understand constructors and inheritance.
- You understand constructor execution order.
- You can use the super keyword.
- You can call parent constructors.
- You can call parent methods.
- You understand constructor chaining.
- You understand method inheritance.
- You understand method overriding.
- You know method overriding rules.
- You can use @Override.
- You understand field hiding.
- You understand static method hiding.
- You understand single inheritance.
- You understand multilevel inheritance.
- You understand hierarchical inheritance.
- You understand why Java avoids multiple class inheritance.
- You understand the Object class.
- You understand upcasting.
- You understand downcasting.
- You can use instanceof.
- You understand pattern matching with instanceof.
- You understand final classes.
- You understand final methods.
- You understand abstract classes and inheritance.
- You understand inheritance and encapsulation.
- You know the difference between inheritance and composition.
- You know when to use inheritance.
- You know when to avoid inheritance.
- You can design inheritance hierarchies.
- You can identify common inheritance errors.
- You know inheritance best practices.
- You are ready to learn Polymorphism in Java.