Topic 8 of 13 · Lectures 11–12
Overriding, Polymorphism & Abstract Classes
Replacing inherited behaviour with method overriding, dynamic method dispatch, casting within a hierarchy, abstract classes, final classes and methods, and using library classes.
← → move between slides · F full screen · M slide list
Before we start
Why this matters
One loop, one line — for (Shape s : shapes) total += s.area(); — correctly adds the areas of circles, rectangles and triangles. How does one line know three formulas?
Each object carries its real class with it. When the program runs, Java looks at the object, not the variable, to decide which area() to call. That is dynamic method dispatch, the engine behind polymorphism.
Abstract classes then let you say “every Shape has an area” without pretending to know a formula for a shape in general.
Outline · Lectures 11–12
Topics in this chapter
Select a topic to jump to the slide that explains it.
Concept 1 of 5
Method overriding
class Animal {
String sound() { return "..."; }
}
class Dog extends Animal {
@Override
String sound() { return "Woof"; }
}
class Cat extends Animal {
@Override
public String sound() { return "Meow"; } // wider access OK
}- A subclass overrides a method by declaring the same name, parameters and a compatible return type.
- Access may be the same or wider, never narrower (protected → public is OK).
@Overrideasks the compiler to check that you really are overriding — a typo likesound(int x)becomes an error instead of a silent overload.static,privateandfinalmethods cannot be overridden.
Concept 2 of 5
Overloading vs overriding
| Overloading | Overriding | |
|---|---|---|
| Where | Same class (or subclass) | Subclass of the declaring class |
| Parameters | Must differ | Must be the same |
| Return type | Can be anything | Same or a subtype (covariant) |
| Chosen | At compile time from argument types | At run time from the object’s class |
| Purpose | Convenience: several ways to call | Specialise inherited behaviour |
| Also called | Static (compile-time) polymorphism | Dynamic (run-time) polymorphism |
Concept 3 of 5
Dynamic method dispatch
Dynamic method dispatch
Animal a; // reference type: Animal a = new Dog(); System.out.println(a.sound()); // Woof a = new Cat(); System.out.println(a.sound()); // Meow // a.fetch(); ✗ compile error: Animal has no fetch()
- A superclass reference can refer to any subclass object (upcasting is automatic).
- Compile time: the reference type decides which methods you may call.
- Run time: the object’s actual class decides which version runs.
Interactive
Dynamic dispatch explorer
Interactive
Downcasting and instanceof
Concept 4 of 5
Abstract classes
Abstract classes
abstract class Shape {
protected String name;
Shape(String name) { this.name = name; }
abstract double area(); // no body
String describe() { // concrete method
return name + " with area " + area();
}
}
class Circle extends Shape {
private double r;
Circle(double r) { super("Circle"); this.r = r; }
double area() { return Math.PI * r * r; }
}- An abstract method has no body; an abstract class cannot be instantiated:
new Shape()✗. - A subclass must implement every abstract method — or be abstract itself.
- Abstract classes can still have fields, constructors and concrete methods.
Step through the code
Trace: polymorphic area()
One array, three objects, one call. Watch which area() frame appears for each element.
Step through the code
Trace: polymorphic area() (cont.)
Interactive
Polymorphic shapes
Concept 5 of 5
final classes and methods
class Account {
final void audit() { /* must not change */ }
}
class Savings extends Account {
void audit() { } // ✗ cannot override final method
}
final class Money { }
class Taka extends Money { } // ✗ cannot inherit from final- A final method keeps its behaviour in every subclass — useful for security checks and template steps.
- A final class cannot be extended:
String,Integer,Math. abstract finalis a contradiction and does not compile.- final calls can be bound early, which also lets the JIT inline them.
Code example
Using library classes
import java.util.*; ArrayList<String> names = new ArrayList<>(); names.add("Sadia"); names.add("Imran"); names.add("Mitu"); Collections.sort(names); System.out.println(names + " size=" + names.size()); Integer boxed = 42; // autoboxing int n = Integer.parseInt("123") + boxed; // wrapper helpers System.out.println(n + "" + Integer.toBinaryString(10)); System.out.println(Math.max(3, 8) + "" + Math.sqrt(49) + "" + Math.round(2.5)); Object o = names; // polymorphism again System.out.println(o instanceof List);[Imran, Mitu, Sadia] size=3 165 1010 8 7.0 3 true
- The Java library (API) is thousands of ready-made classes. Read their documentation for constructors, methods and exceptions.
- Wrapper classes (
Integer,Double, …) let primitives be used as objects in collections.
Worked example 1 of 3
Worked example 1
class A { void f() { System.out.print("A"); } }class B extends A { void f() { System.out.print("B"); } }A x = new B(); x.f(); ((A) x).f();Show the solution
Worked example 2 of 3
Worked example 2
Animal a = new Dog();, what happens with (1) Dog d = a; (2) Dog d = (Dog) a; (3) Cat c = (Cat) a;?Show the solution
- Does not compile: an Animal is not necessarily a Dog.
- Compiles and works.
- Compiles, but throws
ClassCastExceptionat run time because the object is a Dog.
Worked example 3 of 3
Worked example 3
Employee with abstract earnings() and two concrete subclasses.Show the solution
abstract class Employee {
protected String name;
Employee(String name) { this.name = name; }
abstract double earnings();
}
class Salaried extends Employee {
private double monthly;
Salaried(String n, double m) { super(n); monthly = m; }
double earnings() { return monthly; }
}
class Hourly extends Employee {
private double rate; private int hours;
Hourly(String n, double r, int h) { super(n); rate = r; hours = h; }
double earnings() { return rate * hours; }
}Practice
Practice (1 of 2)
Try each one on paper first, then check your answer.
Show the answer
Show the answer
Shape s = new Circle(1); System.out.println(s instanceof Shape);Show the answer
Practice
Practice (2 of 2)
Try each one on paper first, then check your answer.
String declared final?Show the answer
speak() only on the Dogs in an Animal[].Show the answer
for (Animal a : zoo)
if (a instanceof Dog d) // Java 16 pattern
d.speak();Show the answer
Check yourself
Quiz
Summary
Summary
- Overriding redefines an inherited method with the same signature; @Override lets the compiler check it.
- The reference type limits which methods you may call; the object’s class decides which version runs.
- Downcasting needs an explicit cast and is checked at run time; use instanceof to test first.
- Abstract classes cannot be instantiated and may declare abstract methods that subclasses must implement.
- final methods cannot be overridden; final classes cannot be extended.