Inheritance & Polymorphism
Class inheritance and method overriding
Inheritance Fundamentals
Inheritance allows a class to inherit properties and methods from another class, promoting code reusability and establishing “is-a” relationships.
Parent Class
Base class that provides common features
Child Class
Derived class that inherits and extends
extends Keyword
Establishes inheritance relationship
Basic Inheritance Example
Animal - Dog Example
// Parent Class
class Animal {
protected String name;
protected int age;
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public void eat() {
System.out.println(name + " is eating");
}
public void sleep() {
System.out.println(name + " is sleeping");
}
}
// Child Class
class Dog extends Animal {
private String breed;
public Dog(String name, int age, String breed) {
super(name, age); // Call parent constructor
this.breed = breed;
}
public void bark() {
System.out.println(name + " is barking");
}
}
Types of Inheritance
Single Inheritance
One child class inherits from one parent class
Animal
|
Dog
Multilevel Inheritance
Chain of inheritance across multiple levels
Animal
|
Dog
|
Bulldog
Hierarchical Inheritance
Multiple child classes inherit from one parent
Animal
/ \
Dog Cat
Multilevel Inheritance Example
Three-Level Hierarchy
class Vehicle {
protected String brand;
public void start() {
System.out.println("Vehicle started");
}
}
class Car extends Vehicle {
protected int doors;
public void drive() {
System.out.println("Car is driving");
}
}
class SportsCar extends Car {
private boolean turbo;
public void activateTurbo() {
System.out.println("Turbo activated!");
}
}
Important Note
Multiple Inheritance: Java doesn’t support multiple class inheritance but supports multiple interface inheritance.
Polymorphism Concepts
Polymorphism allows objects of different types to be treated as objects of a common base type. “One interface, multiple implementations.”
Compile-time Polymorphism
Method Overloading
Same method name, different parameters
Runtime Polymorphism
Method Overriding
Child class provides specific implementation
Runtime Polymorphism Example
Dynamic Method Dispatch
class Shape {
public void draw() {
System.out.println("Drawing a shape");
}
public double area() {
return 0;
}
}
class Circle extends Shape {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
@Override
public void draw() {
System.out.println("Drawing a circle");
}
@Override
public double area() {
return Math.PI * radius * radius;
}
}
class Rectangle extends Shape {
private double length, width;
public Rectangle(double length, double width) {
this.length = length;
this.width = width;
}
@Override
public void draw() {
System.out.println("Drawing a rectangle");
}
@Override
public double area() {
return length * width;
}
}
// Usage
public class Main {
public static void main(String[] args) {
Shape[] shapes = {
new Circle(5),
new Rectangle(4, 6)
};
for (Shape shape : shapes) {
shape.draw(); // Calls appropriate method
System.out.println("Area: " + shape.area());
}
}
}
Polymorphism Benefits
- Flexibility: Add new types without changing existing code
- Maintainability: Single interface for multiple implementations
- Extensibility: Easy to extend functionality
- Abstraction: Hide implementation details
Method Overriding
Method overriding allows a child class to provide a specific implementation of a method already defined in its parent class.
Overriding Rules & Example
Complete Override Example
class Employee {
protected String name;
protected double baseSalary;
public Employee(String name, double baseSalary) {
this.name = name;
this.baseSalary = baseSalary;
}
public double calculateSalary() {
return baseSalary;
}
public void displayInfo() {
System.out.println("Employee: " + name);
}
}
class Manager extends Employee {
private double bonus;
public Manager(String name, double baseSalary, double bonus) {
super(name, baseSalary);
this.bonus = bonus;
}
@Override
public double calculateSalary() {
return baseSalary + bonus; // Enhanced calculation
}
@Override
public void displayInfo() {
super.displayInfo(); // Call parent method
System.out.println("Role: Manager");
}
}
| Rule | Description | Example |
|---|---|---|
| Same Method Signature | Name, parameters must match exactly | public void draw() |
| Access Modifier | Can’t reduce visibility | protected -> public (OK) |
| Return Type | Same or covariant return type | Object -> String (OK) |
| @Override Annotation | Optional but recommended | Compile-time checking |
Method Overloading
Method overloading allows multiple methods with the same name but different parameters in the same class.
Overloading Examples
Calculator with Overloaded Methods
class Calculator {
// Different number of parameters
public int add(int a, int b) {
return a + b;
}
public int add(int a, int b, int c) {
return a + b + c;
}
// Different parameter types
public double add(double a, double b) {
return a + b;
}
// Different parameter order
public String add(String str, int num) {
return str + num;
}
public String add(int num, String str) {
return num + str;
}
}
// Usage
Calculator calc = new Calculator();
System.out.println(calc.add(5, 3)); // 8
System.out.println(calc.add(5, 3, 2)); // 10
System.out.println(calc.add(5.5, 3.2)); // 8.7
System.out.println(calc.add("Result: ", 42)); // Result: 42
Method Overloading
- Same class
- Same method name
- Different parameters
- Compile-time polymorphism
- Static binding
Method Overriding
- Parent-child classes
- Same method signature
- Different implementation
- Runtime polymorphism
- Dynamic binding
Best Practices
Access Modifiers
- Use
protectedfor inheritance - Keep fields
privatewhen possible - Provide
publicmethods for access
Method Design
- Always use
@Overrideannotation - Call
super()in constructors - Keep method names descriptive
Class Design
- Follow “is-a” relationship rule
- Prefer composition over inheritance
- Keep inheritance hierarchies shallow
Common Pitfalls to Avoid
Watch Out For
- Deep Inheritance: Avoid more than 3-4 levels
- Overriding private methods: Not possible, creates new method
- Constructor chaining: Always call super() explicitly
- Method hiding: Static methods are hidden, not overridden
Quick Reference
Inheritance Keywords
extends- Inherit from classsuper- Access parent membersthis- Current object reference@Override- Override annotation
Access Levels
private- Same class onlyprotected- Package + subclassespublic- Everywheredefault- Package only
Remember
Inheritance models “is-a” relationships - A Dog IS-A Animal
Polymorphism provides flexibility - One interface, many implementations