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
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 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
| Aspect | Method Overloading | Method Overriding |
|---|---|---|
| Definition | Multiple methods with same name, different parameters | Child class redefines parent class method |
| Inheritance | Not required (same class) | Required (parent-child relationship) |
| Method Signature | Different parameters | Same signature |
| Return Type | Can be different | Must be same or covariant |
| Access Modifier | Can be different | Cannot be more restrictive |
| Binding | Compile-time (Static) | Runtime (Dynamic) |
| Polymorphism | Compile-time polymorphism | Runtime polymorphism |
| Performance | Faster (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!

