DEV Community

Rajesh Bhola
Rajesh Bhola

Posted on

Part 5 - IS-A Relationship (Inheritance) in Java

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

}
Enter fullscreen mode Exit fullscreen mode

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();

    }

}
Enter fullscreen mode Exit fullscreen mode

Output

Method from Parent
Method from Child
Enter fullscreen mode Exit fullscreen mode

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)

           +------------------+
Enter fullscreen mode Exit fullscreen mode

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");
    }

}
Enter fullscreen mode Exit fullscreen mode
Child child = new Child();

child.methodOne();

child.methodTwo();
Enter fullscreen mode Exit fullscreen mode

Output

Parent Method
Child Method
Enter fullscreen mode Exit fullscreen mode

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();
Enter fullscreen mode Exit fullscreen mode

Compile-Time Error

cannot find symbol
method methodTwo()
Enter fullscreen mode Exit fullscreen mode

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();
Enter fullscreen mode Exit fullscreen mode

Output

Parent Method
Enter fullscreen mode Exit fullscreen mode

Trying to call a child-specific method:

parent.methodTwo();
Enter fullscreen mode Exit fullscreen mode

Compile-Time Error

cannot find symbol
method methodTwo()
Enter fullscreen mode Exit fullscreen mode

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 in Child, Java will invoke the Child implementation 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();
Enter fullscreen mode Exit fullscreen mode

Compile-Time Error

incompatible types:
Parent cannot be converted to Child
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Similarly,

Child IS-A Parent

Parent IS-NOT necessarily a Child
Enter fullscreen mode Exit fullscreen mode

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");
    }

}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Java automatically adds it.

Example:

class Employee {

}
Enter fullscreen mode Exit fullscreen mode

This is treated as:

class Employee extends Object {

}
Enter fullscreen mode Exit fullscreen mode

Therefore, every class inherits useful methods such as:

  • toString()
  • equals()
  • hashCode()
  • getClass()

Direct vs Indirect Child of Object

class A {

}

class B extends A {

}
Enter fullscreen mode Exit fullscreen mode
Object

   │

   ▼

   A

   │

   ▼

   B
Enter fullscreen mode Exit fullscreen mode
  • A is a direct child of Object.
  • B is an indirect child of Object.

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Java does not support multiple inheritance through classes.

class Child extends ParentOne, ParentTwo {

}
Enter fullscreen mode Exit fullscreen mode

Compile-Time Error

'{'
expected
Enter fullscreen mode Exit fullscreen mode

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 {

}
Enter fullscreen mode Exit fullscreen mode

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 {

}
Enter fullscreen mode Exit fullscreen mode

Compile-Time Error

cyclic inheritance involving A
Enter fullscreen mode Exit fullscreen mode

Indirect Cycle

class A extends B {

}

class B extends A {

}
Enter fullscreen mode Exit fullscreen mode

Compile-Time Error

cyclic inheritance involving A
Enter fullscreen mode Exit fullscreen mode

Visual Explanation

A

▲

│

▼

B
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

extends always comes before implements.


Common Beginner Mistakes

Mistake 1: Assuming Inheritance Works Both Ways

❌ Incorrect

Parent parent = new Parent();

parent.methodTwo();
Enter fullscreen mode Exit fullscreen mode

The parent cannot access child-specific members.


Mistake 2: Assigning a Parent Object to a Child Reference

❌ Incorrect

Child child = new Parent();
Enter fullscreen mode Exit fullscreen mode

A parent object is not necessarily a child object.


Mistake 3: Confusing Upcasting with Method Availability

Parent parent = new Child();
Enter fullscreen mode Exit fullscreen mode

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();
Enter fullscreen mode Exit fullscreen mode

This is called upcasting.


4. Can a child reference hold a parent object?

Expected answer

No.

Child child = new Parent();
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Examples:

Dog IS-A Animal

Manager IS-A Employee

SavingsAccount IS-A Account
Enter fullscreen mode Exit fullscreen mode

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 extends keyword 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.
  • Throwable is 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)