Inheritance Basics

extends keyword and IS-A relationship

Interview Relevant: Core OOP principle
6 min read

Inheritance in Java

Inheritance allows a class to inherit properties and methods from another class. The extends keyword establishes an IS-A relationship.

Key Terminology

  • Parent/Super/Base Class: The class being inherited from
  • Child/Sub/Derived Class: The class that inherits
  • IS-A Relationship: Child IS-A type of Parent
  • extends: Keyword to establish inheritance

🔑 Key Rule: Java supports single inheritance only - a class can extend only ONE class. But multiple levels are allowed.

✓ Benefits: Code reuse, method overriding, runtime polymorphism, establishing type hierarchies.

Code Examples

Basic inheritance with extends

java
1// Basic Inheritance Example
2public class Animal {
3    protected String name;
4    
5    public Animal(String name) {
6        this.name = name;
7    }
8    
9    public void eat() {
10        System.out.println(name + " is eating");
11    }
12    
13    public void sleep() {
14        System.out.println(name + " is sleeping");
15    }
16}
17
18// Dog IS-A Animal
19public class Dog extends Animal {
20    private String breed;
21    
22    public Dog(String name, String breed) {
23        super(name);  // Call parent constructor
24        this.breed = breed;
25    }
26    
27    // Additional method
28    public void bark() {
29        System.out.println(name + " is barking");
30    }
31}
32
33// Usage
34Dog dog = new Dog("Buddy", "Labrador");
35dog.eat();    // Inherited from Animal
36dog.sleep();  // Inherited from Animal
37dog.bark();   // Dog's own method

What gets inherited

java
1// What is inherited?
2public class Parent {
3    public int publicField = 1;
4    protected int protectedField = 2;
5    int defaultField = 3;  // package-private
6    private int privateField = 4;  // NOT inherited
7    
8    public void publicMethod() {}
9    protected void protectedMethod() {}
10    void defaultMethod() {}
11    private void privateMethod() {}  // NOT inherited
12    
13    // Constructor is NOT inherited, but called via super()
14    public Parent() {
15        System.out.println("Parent constructor");
16    }
17}
18
19public class Child extends Parent {
20    public Child() {
21        // super() is called automatically if not explicit
22        System.out.println("Child constructor");
23    }
24    
25    public void test() {
26        // Can access:
27        System.out.println(publicField);     // ✓
28        System.out.println(protectedField);  // ✓
29        System.out.println(defaultField);    // ✓ (same package)
30        // System.out.println(privateField); // ✗ Not inherited!
31        
32        publicMethod();     // ✓
33        protectedMethod();  // ✓
34        // privateMethod(); // ✗ Not inherited!
35    }
36}

IS-A relationship enables polymorphism

java
1// IS-A relationship and polymorphism
2class Vehicle {
3    public void start() {
4        System.out.println("Vehicle starting");
5    }
6}
7
8class Car extends Vehicle {
9    @Override
10    public void start() {
11        System.out.println("Car starting with key");
12    }
13}
14
15class Motorcycle extends Vehicle {
16    @Override
17    public void start() {
18        System.out.println("Motorcycle starting with kick");
19    }
20}
21
22// Polymorphism: Parent reference to Child object
23Vehicle v1 = new Car();        // Car IS-A Vehicle
24Vehicle v2 = new Motorcycle(); // Motorcycle IS-A Vehicle
25
26v1.start();  // "Car starting with key" - runtime polymorphism!
27v2.start();  // "Motorcycle starting with kick"
28
29// Array of parent type can hold children
30Vehicle[] vehicles = {new Car(), new Motorcycle()};
31for (Vehicle v : vehicles) {
32    v.start();  // Calls appropriate version
33}

Real-world inheritance hierarchy

java
1// Real-world Example: Employee Hierarchy
2public class Employee {
3    protected String name;
4    protected double baseSalary;
5    
6    public Employee(String name, double salary) {
7        this.name = name;
8        this.baseSalary = salary;
9    }
10    
11    public double calculateSalary() {
12        return baseSalary;
13    }
14    
15    public String getInfo() {
16        return name + ": $" + calculateSalary();
17    }
18}
19
20public class Manager extends Employee {
21    private double bonus;
22    
23    public Manager(String name, double salary, double bonus) {
24        super(name, salary);
25        this.bonus = bonus;
26    }
27    
28    @Override
29    public double calculateSalary() {
30        return baseSalary + bonus;  // Can access protected
31    }
32}
33
34public class Developer extends Employee {
35    private int overtimeHours;
36    
37    public Developer(String name, double salary, int overtime) {
38        super(name, salary);
39        this.overtimeHours = overtime;
40    }
41    
42    @Override
43    public double calculateSalary() {
44        return baseSalary + (overtimeHours * 50);
45    }
46}
47
48// Use polymorphically
49Employee[] team = {
50    new Manager("Alice", 80000, 10000),
51    new Developer("Bob", 60000, 20)
52};
53
54for (Employee e : team) {
55    System.out.println(e.getInfo());
56}

Use Cases

  • Code reuse across related classes
  • Creating type hierarchies
  • Enabling polymorphism
  • Framework extension points
  • Template method pattern
  • Common behavior in base class

Common Mistakes to Avoid

  • Using inheritance for code reuse only (prefer composition)
  • Deep inheritance hierarchies
  • Breaking IS-A relationship
  • Inheriting from concrete classes
  • Forgetting to call super constructor
  • Not understanding what is inherited