Object Oriented Programming with JavaUnit 46 min read
Inheritance, Method Overriding & Polymorphism in Java
Unit 4 of Object Oriented Programming with Java covers inheritance hierarchies, method overriding rules, runtime polymorphism, and the super keyword, with real-world examples from Nepalese apps like eSewa and Ncell, plus code traces and comparison tables.
Key Concepts & Definitions
Inheritance: The "Is-A" Relationship
Inheritance allows a subclass (child) to inherit fields and methods from a superclass (parent). It promotes code reusability and establishes a hierarchical relationship.
classDiagram
class Animal {
<<abstract>>
+void makeSound()
}
class Dog {
+void makeSound()
}
class Cat {
+void makeSound()
}
Animal <|-- Dog
Animal <|-- CatReal-world analogy:
- A Dog is an Animal (inherits
eat(),sleep()). - A Scooter is a Vehicle (inherits
start(),stop()).
Types of Inheritance in Java
Java supports single-level, multilevel, hierarchical, and multiple inheritance via interfaces (but not classes).
| Type | Diagram Example | Code Example |
|---|---|---|
| Single-level | A → B |
class B extends A |
| Multilevel | A → B → C |
class C extends B |
| Hierarchical | A → B, A → C |
Two classes extend A |
| Multiple (Interfaces) | A ← B, A ← C (via implements) |
class A implements B, C |
Why no multiple inheritance for classes?
- Diamond Problem: Ambiguity if two parents have the same method.
class A { void show() {} } class B extends A { void show() {} } class C extends A { void show() {} } // class D extends B, C { } → Compile-time error!
Method Overriding: Runtime Polymorphism
Overriding occurs when a subclass provides a specific implementation of a method already defined in its superclass.
Rules for Overriding
- Must have the same method signature (name, parameters, return type).
- Access modifier cannot be more restrictive (e.g.,
public→privateis invalid). - Exception handling: Subclass can throw unchecked exceptions or a subset of checked exceptions.
@Overrideannotation: Recommended for clarity.
class Vehicle {
void start() { System.out.println("Vehicle started"); }
}
class Car extends Vehicle {
@Override
void start() { System.out.println("Car engine started"); }
}
Trace Example:
Vehicle v = new Car(); // Upcasting
v.start(); // Output: "Car engine started" (runtime polymorphism)
The super Keyword
super(): Calls the parent class constructor.super.method(): Invokes the parent’s overridden method.
class Parent {
Parent() { System.out.println("Parent constructor"); }
void display() { System.out.println("Parent display"); }
}
class Child extends Parent {
Child() {
super(); // Calls Parent()
System.out.println("Child constructor");
}
@Override
void display() {
super.display(); // Calls Parent.display()
System.out.println("Child display");
}
}
Output:
Parent constructor
Child constructor
Parent display
Child display
Real-World Applications in Nepal
1. eSewa (Digital Payment System)
- Inheritance:
PaymentGateway(superclass) →eSewaPayment(subclass).- Inherits
processPayment()but overridesvalidateUser()for eSewa-specific checks.
- Inherits
- Polymorphism:
PaymentGateway gateway = new eSewaPayment();allows treating eSewa payments uniformly with other gateways.
2. Ncell (Mobile Network)
- Method Overriding:
PrepaidPlan(superclass) →NcellPrepaid(subclass).- Overrides
calculateBill()to apply Ncell’s tariff rules.
- Overrides
- Example Trace:
PrepaidPlan plan = new NcellPrepaid(1000); plan.calculateBill(); // Uses Ncell’s logic, not generic PrepaidPlan.
3. Daraz (E-Commerce)
- Hierarchical Inheritance:
Order(superclass) →FoodOrder,ElectronicsOrder(subclasses).- Both inherit
placeOrder()but overridecalculateTax()differently.
- Both inherit
Comparison: Inheritance vs. Composition
| Feature | Inheritance | Composition |
|---|---|---|
| Relationship | "Is-A" (e.g., Dog is an Animal) | "Has-A" (e.g., Car has an Engine) |
| Coupling | Tight (subclass depends on superclass) | Loose (flexible dependencies) |
| Reusability | High (inherits fields/methods) | High (delegates behavior) |
| Example | class Dog extends Animal |
class Car { Engine engine; } |
When to use which?
- Use inheritance for hierarchical relationships (e.g.,
Shape → Circle). - Use composition for "has-a" relationships (e.g.,
Computer → Keyboard).
Worked Example: Bank Loan Calculator
Scenario: A bank offers different loan types (HomeLoan, CarLoan) inheriting from Loan.
class Loan {
double principal;
Loan(double p) { principal = p; }
double calculateInterest() { return principal * 0.1; } // 10% default
}
class HomeLoan extends Loan {
HomeLoan(double p) { super(p); }
@Override
double calculateInterest() { return principal * 0.08; } // 8% override
}
Trace:
Loan loan1 = new Loan(100000);
Loan loan2 = new HomeLoan(100000);
System.out.println(loan1.calculateInterest()); // 10000.0
System.out.println(loan2.calculateInterest()); // 8000.0 (overridden)
Common Pitfalls & Best Practices
- Avoid deep inheritance hierarchies (hard to maintain).
- Prefer composition over inheritance for flexibility.
- Use
@Overrideto catch errors early. - Finalize methods/classes when no overriding is needed:
class FinalExample { final void criticalMethod() { /* ... */ } }
Exam Tip
- Diagrams: Draw UML class diagrams for inheritance hierarchies (e.g.,
Animal → Dog → Puppy). - Code Traces: Always show output for polymorphic calls (e.g.,
Animal a = new Dog(); a.speak();). - Key Terms:
- Upcasting:
Dog d = new Puppy(); Animal a = d;(valid). - Downcasting:
Animal a = new Dog(); Dog d = (Dog) a;(requires cast).
- Upcasting:
- Short-Answer Questions:
- "What is the output of
super.method()in overriding?" - "Why can’t Java support multiple inheritance for classes?"
- "What is the output of
- Programming Questions:
- Write a program with 2 classes where one overrides a method and use polymorphism to call it.
Visual Summary:
flowchart TD
A["Inheritance"] --> B["Code Reusability"]
A --> C["Runtime Polymorphism"]
C --> D["Method Overriding"]
D --> E["super Keyword"]
E --> F["Constructor Chaining"]Based on the TU BIM syllabus for Object Oriented Programming with Java (IT234), unit 4.
Discussion
Loading…