Skip to main content
  1. Resources/
  2. Study Materials/
  3. Information & Communication Technology Engineering/
  4. ICT Semester 4/
  5. Java Programming (4343203)/

7 mins· ·
Milav Dabgar
Author
Milav Dabgar
Experienced lecturer in the electrical and electronic manufacturing industry. Skilled in Embedded Systems, Image Processing, Data Science, MATLAB, Python, STM32. Strong education professional with a Master’s degree in Communication Systems Engineering from L.D. College of Engineering - Ahmedabad.
Java Programming - Inheritance and Polymorphism

Java Programming Language

Chapter 6: Inheritance and Polymorphism

Advanced OOP Concepts


Course: 4343203 - Java Programming

What We'll Cover

  • Inheritance Fundamentals
  • Types of Inheritance
  • super Keyword
  • Method Overriding
  • Polymorphism Concepts
  • Method Overloading vs Overriding
  • Dynamic Method Dispatch
  • Final Classes and Methods

Inheritance Hierarchy

Java Inheritance Hierarchy

Inheritance Fundamentals

Inheritance allows a class to inherit properties and methods from another class

Inheritance Terminology

Key Terms:

  • Parent Class: Base class, Superclass
  • Child Class: Derived class, Subclass
  • extends: Keyword to inherit from a class
  • IS-A Relationship: Child IS-A type of Parent

Basic Inheritance:


// Parent class
class Animal {
    String name;
    int age;
    
    void eat() {
        System.out.println("Animal is eating");
    }
    
    void sleep() {
        System.out.println("Animal is sleeping");
    }
}

// Child class
class Dog extends Animal {
    String breed;
    
    void bark() {
        System.out.println("Dog is barking");
    }
}
                            

Usage:


public class TestInheritance {
    public static void main(String[] args) {
        Dog dog = new Dog();
        
        // Inherited properties and methods
        dog.name = "Buddy";
        dog.age = 3;
        dog.eat();    // From Animal
        dog.sleep();  // From Animal
        
        // Own properties and methods
        dog.breed = "Labrador";
        dog.bark();   // Own method
    }
}
                            

Benefits of Inheritance

Code Reusability

  • Reuse parent class code
  • Avoid duplication
  • Maintain consistency

Extensibility

  • Add new features
  • Modify behavior
  • Specialize functionality

Polymorphism

  • One interface, many forms
  • Runtime method resolution
  • Flexible code design

Types of Inheritance

Java supports single inheritance but achieves multiple inheritance through interfaces

Single Inheritance

One parent, one child:


class Vehicle {
    int speed;
    String fuel;
    
    void start() {
        System.out.println("Vehicle started");
    }
}

class Car extends Vehicle {
    int doors;
    
    void accelerate() {
        speed += 10;
        System.out.println("Car accelerating");
    }
}
                            

Multilevel Inheritance:


class Vehicle {
    void start() {
        System.out.println("Vehicle started");
    }
}

class Car extends Vehicle {
    void accelerate() {
        System.out.println("Car accelerating");
    }
}

class SportsCar extends Car {
    void turboBoost() {
        System.out.println("Turbo activated!");
    }
}
                            

Hierarchical Inheritance

One parent, multiple children:


class Animal {
    void eat() {
        System.out.println("Animal eating");
    }
}

class Dog extends Animal {
    void bark() {
        System.out.println("Dog barking");
    }
}

class Cat extends Animal {
    void meow() {
        System.out.println("Cat meowing");
    }
}

class Bird extends Animal {
    void fly() {
        System.out.println("Bird flying");
    }
}
                            

Why No Multiple Inheritance?

Diamond Problem:
  • Ambiguity in method resolution
  • Conflicting implementations
  • Complexity in inheritance
Java's Solution:
  • Single class inheritance
  • Multiple interface implementation
  • Clear inheritance hierarchy

The super Keyword

super refers to the immediate parent class object

Uses of super Keyword

1. Access Parent Variables:


class Animal {
    String name = "Animal";
}

class Dog extends Animal {
    String name = "Dog";
    
    void printNames() {
        System.out.println(name);        // Dog
        System.out.println(super.name);  // Animal
    }
}
                            

2. Call Parent Methods:


class Animal {
    void eat() {
        System.out.println("Animal eating");
    }
}

class Dog extends Animal {
    void eat() {
        super.eat(); // Call parent method
        System.out.println("Dog eating bones");
    }
}
                            

3. Call Parent Constructor:


class Animal {
    String name;
    int age;
    
    Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

class Dog extends Animal {
    String breed;
    
    Dog(String name, int age, String breed) {
        super(name, age); // Must be first statement
        this.breed = breed;
    }
    
    void displayInfo() {
        System.out.println("Name: " + name);
        System.out.println("Age: " + age);
        System.out.println("Breed: " + breed);
    }
}
                            

Important: super() constructor call must be the first statement in child constructor

Method Overriding

Method Overriding allows child class to provide specific implementation of parent method

Method Overriding vs Overloading Comparison

Method Overriding vs Overloading Comparison

Method Overriding Rules

Overriding Requirements:

  • Same method name, parameters, and return type
  • Child class method cannot have stricter access modifier
  • Cannot override static, final, or private methods
  • Use @Override annotation (recommended)

Example:


class Animal {
    void makeSound() {
        System.out.println("Animal makes sound");
    }
    
    void move() {
        System.out.println("Animal moves");
    }
}

class Dog extends Animal {
    @Override
    void makeSound() {
        System.out.println("Dog barks: Woof!");
    }
    
    @Override
    void move() {
        System.out.println("Dog runs on four legs");
    }
}

class Cat extends Animal {
    @Override
    void makeSound() {
        System.out.println("Cat meows: Meow!");
    }
}
                            

Usage:


public class TestOverriding {
    public static void main(String[] args) {
        Animal animal1 = new Dog();
        Animal animal2 = new Cat();
        
        animal1.makeSound(); // Dog barks: Woof!
        animal1.move();      // Dog runs on four legs
        
        animal2.makeSound(); // Cat meows: Meow!
        animal2.move();      // Animal moves
    }
}
                            
@Override Benefits:
  • Compile-time checking
  • Code readability
  • Prevents typos

Polymorphism

Polymorphism means "many forms" - one interface, multiple implementations

Types of Polymorphism

Compile-time Polymorphism

Method Overloading:

class Calculator {
    int add(int a, int b) {
        return a + b;
    }
    
    double add(double a, double b) {
        return a + b;
    }
    
    int add(int a, int b, int c) {
        return a + b + c;
    }
}
                                
  • Same method name
  • Different parameters
  • Resolved at compile time

Runtime Polymorphism

Method Overriding:

class Shape {
    void draw() {
        System.out.println("Drawing shape");
    }
}

class Circle extends Shape {
    @Override
    void draw() {
        System.out.println("Drawing circle");
    }
}

class Rectangle extends Shape {
    @Override
    void draw() {
        System.out.println("Drawing rectangle");
    }
}
                                
  • Same method signature
  • Different implementations
  • Resolved at runtime

Practical Polymorphism Example


class Employee {
    String name;
    double salary;
    
    Employee(String name, double salary) {
        this.name = name;
        this.salary = salary;
    }
    
    double calculateBonus() {
        return salary * 0.1; // 10% bonus
    }
    
    void displayInfo() {
        System.out.println("Name: " + name + ", Salary: " + salary);
        System.out.println("Bonus: " + calculateBonus());
    }
}

class Manager extends Employee {
    Manager(String name, double salary) {
        super(name, salary);
    }
    
    @Override
    double calculateBonus() {
        return salary * 0.2; // 20% bonus for managers
    }
}

class Developer extends Employee {
    Developer(String name, double salary) {
        super(name, salary);
    }
    
    @Override
    double calculateBonus() {
        return salary * 0.15; // 15% bonus for developers
    }
}

public class PolymorphismDemo {
    public static void main(String[] args) {
        Employee[] employees = {
            new Employee("John", 50000),
            new Manager("Alice", 80000),
            new Developer("Bob", 70000)
        };
        
        for (Employee emp : employees) {
            emp.displayInfo(); // Different bonus calculations
            System.out.println();
        }
    }
}
                    

Dynamic Method Dispatch

Dynamic Method Dispatch is the mechanism by which a call to an overridden method is resolved at runtime

How Dynamic Dispatch Works

Example:


class Animal {
    void sound() {
        System.out.println("Animal sound");
    }
}

class Dog extends Animal {
    @Override
    void sound() {
        System.out.println("Woof!");
    }
}

class Cat extends Animal {
    @Override
    void sound() {
        System.out.println("Meow!");
    }
}

public class DynamicDispatch {
    public static void main(String[] args) {
        Animal animal;
        
        animal = new Dog();
        animal.sound(); // Woof! (Dog's method)
        
        animal = new Cat();
        animal.sound(); // Meow! (Cat's method)
        
        // Array of animals
        Animal[] animals = {
            new Dog(), new Cat(), new Dog()
        };
        
        for (Animal a : animals) {
            a.sound(); // Different sounds
        }
    }
}
                            

Key Points:

Runtime Resolution:
  • Method determined by object type
  • Not by reference type
  • Happens at runtime
Benefits:
  • Flexible code design
  • Easy to extend
  • Loose coupling
Requirements:
  • Inheritance relationship
  • Method overriding
  • Upcasting (parent reference)

Method Overloading vs Overriding

AspectMethod OverloadingMethod Overriding
DefinitionMultiple methods with same name, different parametersChild class redefines parent class method
InheritanceNot required (same class)Required (parent-child relationship)
Method SignatureDifferent parametersSame signature
Return TypeCan be differentMust be same or covariant
Access ModifierCan be differentCannot be more restrictive
BindingCompile-time (Static)Runtime (Dynamic)
PolymorphismCompile-time polymorphismRuntime polymorphism
PerformanceFaster (compile-time)Slower (runtime resolution)

Final Classes and Methods

final keyword prevents inheritance and method overriding

Final Methods and Classes

Final Methods:


class Animal {
    // Cannot be overridden
    final void breathe() {
        System.out.println("Animal breathing");
    }
    
    // Can be overridden
    void move() {
        System.out.println("Animal moving");
    }
}

class Dog extends Animal {
    // This would cause compilation error
    // void breathe() { } // Error!
    
    @Override
    void move() {
        System.out.println("Dog running");
    }
}
                            

Final Classes:


// Cannot be extended
final class String {
    // String class implementation
}

// This would cause compilation error
// class MyString extends String { } // Error!

final class Math {
    public static final double PI = 3.14159;
    
    public static double sqrt(double a) {
        // Implementation
        return 0;
    }
}
                            
Use Cases:
  • Security-sensitive classes
  • Immutable classes
  • Utility classes
  • Performance optimization

Chapter Summary

Inheritance Concepts:

  • Code reusability through extends
  • IS-A relationship modeling
  • Single inheritance in Java
  • super keyword usage
  • Constructor chaining

Polymorphism Features:

  • Method overloading (compile-time)
  • Method overriding (runtime)
  • Dynamic method dispatch
  • @Override annotation
  • Final methods and classes

Next: Interfaces and Abstract Classes

Thank You!

Questions?


Ready to explore Interfaces and Abstract Classes!