After learning the protective principles of Object-Oriented Programming (OOP)—Data Hiding, Abstraction, Encapsulation, and Tightly Encapsulated Classes—it's time to explore how classes relate to each other.
Java provides two primary relationships between classes:
- IS-A Relationship (Inheritance) ← This article
- HAS-A Relationship (Composition/Aggregation) ← Next article
The IS-A relationship allows one class to inherit the properties and behaviors of another, promoting code reuse, reducing duplication, and creating a natural hierarchy.
In this article, we'll explore the extends keyword, inheritance rules, object reference behavior, multiple inheritance, cyclic inheritance, and common interview questions.
What is the IS-A Relationship?
The IS-A Relationship is another name for Inheritance.
It represents a parent-child relationship where a child class inherits the members of its parent class.
In simple words:
Inheritance is the mechanism by which one class acquires the properties and behaviors of another class.
Java implements inheritance using the extends keyword.
Whenever this sentence makes sense:
- Dog IS-A Animal
- Manager IS-A Employee
- HousingLoan IS-A Loan
- SavingsAccount IS-A Account
then inheritance is usually the correct design choice.
Why Do We Need Inheritance?
Imagine you're developing a banking application.
Every type of bank account needs common functionality such as:
- Deposit money
- Withdraw money
- Check balance
Without inheritance, every account class would repeat the same code.
With inheritance, common behavior is written once in the parent class and reused by all child classes.
This greatly improves:
- Code reusability
- Maintainability
- Readability
- Extensibility
| Without Inheritance | With Inheritance |
|---|---|
| Duplicate code | Reusable code |
| Difficult maintenance | Easy maintenance |
| Repeated business logic | Shared business logic |
| Larger codebase | Cleaner hierarchy |
How Does Java Implement Inheritance?
Java implements the IS-A relationship using the extends keyword.
Syntax
class Parent {
// Parent members
}
class Child extends Parent {
// Child members
}
The child class automatically inherits accessible members from the parent class.
Basic Example
class Parent {
public void methodOne() {
System.out.println("Method from Parent");
}
}
class Child extends Parent {
public void methodTwo() {
System.out.println("Method from Child");
}
}
public class InheritanceDemo {
public static void main(String[] args) {
Child child = new Child();
child.methodOne();
child.methodTwo();
}
}
Output
Method from Parent
Method from Child
How It Works
Step 1
The Parent class defines methodOne().
Step 2
The Child class extends Parent.
Step 3
Child automatically inherits methodOne().
Step 4
The Child object can call both the inherited method and its own method.
Visual Explanation
+------------------+
| Parent |
|------------------|
| methodOne() |
+---------+--------+
▲
│ extends
+---------+--------+
| Child |
|------------------|
| methodOne() | (Inherited)
| methodTwo() | (Own)
+------------------+
The child class receives all accessible members from the parent class without rewriting them.
Rules
Rule 1: Parent Members Are Available to the Child
Everything available in the parent is, by default, available to the child (subject to Java access control rules).
class Parent {
public void methodOne() {
System.out.println("Parent Method");
}
}
class Child extends Parent {
public void methodTwo() {
System.out.println("Child Method");
}
}
Child child = new Child();
child.methodOne();
child.methodTwo();
Output
Parent Method
Child Method
Step-by-Step Explanation
Step 1
The child class extends the parent.
Step 2
methodOne() is inherited.
Step 3
methodTwo() belongs to the child.
Step 4
The child object can call both methods.
Rule 2: Parent Cannot Access Child-Specific Members
Parent parent = new Parent();
parent.methodOne();
parent.methodTwo();
Compile-Time Error
cannot find symbol
method methodTwo()
Why?
A parent object knows only about the members declared in the parent class.
It has no knowledge of members introduced by the child class.
Step-by-Step Explanation
Step 1
A Parent object is created.
Step 2
Only parent members exist inside the object.
Step 3
methodTwo() belongs to Child.
Step 4
The compiler rejects the code.
Rule 3: Parent Reference Can Hold a Child Object
This is one of the most important Java interview concepts.
Parent parent = new Child();
parent.methodOne();
Output
Parent Method
Trying to call a child-specific method:
parent.methodTwo();
Compile-Time Error
cannot find symbol
method methodTwo()
Step-by-Step Explanation
Step 1
A Child object is created.
Step 2
A Parent reference points to it.
Step 3
The reference type determines which methods are accessible at compile time.
Step 4
Only methods declared in Parent can be called through the Parent reference.
Note: If
methodOne()is overridden inChild, Java will invoke theChildimplementation at runtime due to dynamic method dispatch. We'll explore this in the Polymorphism article.
Rule 4: Child Reference Cannot Hold a Parent Object
Child child = new Parent();
Compile-Time Error
incompatible types:
Parent cannot be converted to Child
Why?
A parent object is not necessarily a child object.
Step-by-Step Explanation
Step 1
A Parent object is created.
Step 2
The compiler checks the assignment.
Step 3
Not every parent is a child.
Step 4
Compilation fails.
The Four Most Important Reference Combinations
| Statement | Valid? | Reason |
|---|---|---|
Parent parent = new Parent(); |
✅ Yes | Parent reference to parent object |
Child child = new Child(); |
✅ Yes | Child reference to child object |
Parent parent = new Child(); |
✅ Yes | Upcasting (safe and implicit) |
Child child = new Parent(); |
❌ No | Parent object is not necessarily a child |
Memory Trick
Think about animals.
Dog IS-A Animal
Animal IS-NOT necessarily a Dog
Similarly,
Child IS-A Parent
Parent IS-NOT necessarily a Child
Real-World Example: Loan Management System
Inheritance shines when multiple classes share common functionality.
class Loan {
public void calculateEMI() {
System.out.println("Calculating EMI");
}
public void approve() {
System.out.println("Loan Approved");
}
public void disburse() {
System.out.println("Loan Disbursed");
}
}
class HousingLoan extends Loan {
public void verifyProperty() {
System.out.println("Property Verified");
}
}
class EducationLoan extends Loan {
public void verifyCollege() {
System.out.println("College Verified");
}
}
class VehicleLoan extends Loan {
public void inspectVehicle() {
System.out.println("Vehicle Inspected");
}
}
Without inheritance, calculateEMI(), approve(), and disburse() would need to be duplicated in every loan class.
With inheritance, they are written once and reused everywhere.
Object: The Root of All Java Classes
Every Java class ultimately inherits from the Object class.
Even if you don't write:
class Employee extends Object
Java automatically adds it.
Example:
class Employee {
}
This is treated as:
class Employee extends Object {
}
Therefore, every class inherits useful methods such as:
toString()equals()hashCode()getClass()
Direct vs Indirect Child of Object
class A {
}
class B extends A {
}
Object
│
▼
A
│
▼
B
-
Ais a direct child ofObject. -
Bis an indirect child ofObject.
Throwable: The Root of Exception Hierarchy
Just as Object is the root of all classes, Throwable is the root of Java's exception hierarchy.
Throwable
│
├── Exception
│
└── Error
All exceptions and errors inherit common functionality such as stack traces and messages from Throwable.
Multiple Inheritance
Multiple inheritance means inheriting from more than one parent class.
Parent1 Parent2
\ /
\ /
\ /
Child
Java does not support multiple inheritance through classes.
class Child extends ParentOne, ParentTwo {
}
Compile-Time Error
'{'
expected
Why Doesn't Java Allow It?
If both parent classes contain a method with the same signature but different implementations, the compiler cannot determine which implementation the child should inherit.
This is commonly known as the Diamond Problem, an ambiguity that Java avoids by disallowing multiple inheritance through classes.
Multiple Inheritance Through Interfaces
Java does allow multiple inheritance through interfaces.
interface Printable {
void print();
}
interface Scannable {
void scan();
}
interface MultiFunctionDevice extends Printable, Scannable {
}
This is valid because interfaces primarily define contracts rather than choosing between inherited implementations. If default methods introduce conflicts, the implementing class must explicitly resolve them.
Cyclic Inheritance
A class cannot inherit from itself, directly or indirectly.
Direct Cycle
class A extends A {
}
Compile-Time Error
cyclic inheritance involving A
Indirect Cycle
class A extends B {
}
class B extends A {
}
Compile-Time Error
cyclic inheritance involving A
Visual Explanation
A
▲
│
▼
B
This creates an impossible inheritance hierarchy, so Java rejects it.
extends and implements Rules
| Declaration | Valid? | Explanation |
|---|---|---|
class Child extends Parent |
✅ | Class inherits one class |
interface Child extends ParentOne, ParentTwo |
✅ | Interface can extend multiple interfaces |
class Child implements InterfaceOne, InterfaceTwo |
✅ | Class can implement multiple interfaces |
class Child extends Parent implements InterfaceOne, InterfaceTwo |
✅ | Extend one class, implement multiple interfaces |
class Child implements InterfaceOne extends Parent |
❌ | Incorrect order |
Golden Rule
class Child
extends Parent
implements InterfaceOne, InterfaceTwo
extends always comes before implements.
Common Beginner Mistakes
Mistake 1: Assuming Inheritance Works Both Ways
❌ Incorrect
Parent parent = new Parent();
parent.methodTwo();
The parent cannot access child-specific members.
Mistake 2: Assigning a Parent Object to a Child Reference
❌ Incorrect
Child child = new Parent();
A parent object is not necessarily a child object.
Mistake 3: Confusing Upcasting with Method Availability
Parent parent = new Child();
The reference type controls what members are accessible at compile time. Runtime polymorphism affects overridden methods, not child-specific methods.
Mistake 4: Thinking Java Supports Multiple Class Inheritance
Java allows only one parent class.
Use interfaces when multiple inheritance of type is required.
Interview Questions
1. What is the IS-A relationship?
Why interviewers ask this
To verify your understanding of inheritance.
Expected answer
The IS-A relationship is inheritance, implemented using the extends keyword. It allows a child class to inherit accessible members from its parent class.
Common trap
Confusing IS-A with HAS-A.
2. What is the biggest advantage of inheritance?
Expected answer
Code reusability.
3. Can a parent reference hold a child object?
Expected answer
Yes.
Parent parent = new Child();
This is called upcasting.
4. Can a child reference hold a parent object?
Expected answer
No.
Child child = new Parent();
This results in a compile-time error.
5. Why doesn't Java support multiple inheritance through classes?
Expected answer
To avoid ambiguity (the Diamond Problem) that could arise when multiple parent classes define methods with the same signature.
6. Why does Java support multiple inheritance through interfaces?
Expected answer
Interfaces define contracts. If multiple inherited default methods conflict, the implementing class must resolve the conflict explicitly.
Best Practices
- Use inheritance only when a genuine IS-A relationship exists.
- Place common behavior in the parent class.
- Avoid creating deep inheritance hierarchies.
- Prefer composition (HAS-A) when inheritance doesn't naturally model the relationship.
- Override methods thoughtfully and preserve the parent contract.
- Keep parent classes focused and reusable.
Performance Notes
Inheritance itself has minimal runtime overhead. The primary benefits are code reuse, maintainability, and clean object hierarchies. Performance should rarely be the deciding factor when choosing inheritance.
Quick Memory Trick 🧠
Remember the phrase:
Child
↓
IS-A
↓
Parent
Examples:
Dog IS-A Animal
Manager IS-A Employee
SavingsAccount IS-A Account
If the sentence sounds natural, inheritance is usually appropriate.
FAQ
Is inheritance the same as the IS-A relationship?
Yes. In Java, the IS-A relationship is implemented through inheritance using the extends keyword.
What is the difference between IS-A and HAS-A?
IS-A represents inheritance, while HAS-A represents composition or aggregation. HAS-A models ownership or containment rather than specialization.
Does every Java class inherit from Object?
Yes. Every Java class directly or indirectly extends Object.
Can a class extend multiple classes?
No. A class can extend only one class.
Can an interface extend multiple interfaces?
Yes. An interface can extend any number of interfaces.
Can Java have cyclic inheritance?
No. Cyclic inheritance is illegal and results in a compile-time error.
Key Takeaways
- The IS-A relationship is implemented using inheritance.
- Java uses the
extendskeyword to establish inheritance. - The primary advantage of inheritance is code reusability.
- Parent members are inherited by child classes (subject to access control).
- A parent reference can hold a child object (upcasting).
- A child reference cannot hold a parent object without an explicit downcast, and even then it is only safe if the object is actually a child instance.
- Every Java class ultimately extends
Object. -
Throwableis the root of Java's exception hierarchy. - Java does not support multiple inheritance through classes but does support multiple interface inheritance.
- Cyclic inheritance is not allowed.
If you found this guide helpful, leave a ❤️ and follow for more beginner-friendly Java tutorials, interview questions, and practical coding examples.
Happy Coding!
Top comments (0)