Java Polymorphism
Polymorphism means “many forms”. One method call can behave in different ways depending on the real object. It is the most powerful idea of object oriented programming.
Parent reference, child object
class Shape {
double area() {
return 0;
}
}
class Circle extends Shape {
double r;
Circle(double r) { this.r = r; }
@Override
double area() {
return Math.PI * r * r;
}
}
class Rectangle extends Shape {
double w, h;
Rectangle(double w, double h) { this.w = w; this.h = h; }
@Override
double area() {
return w * h;
}
}
public class Main {
public static void main(String[] args) {
Shape[] shapes = { new Circle(2), new Rectangle(3, 4), new Circle(1) };
double total = 0;
for (Shape s : shapes) {
System.out.printf("%s area = %.2f%n", s.getClass().getSimpleName(), s.area());
total += s.area();
}
System.out.printf("Total area = %.2f%n", total);
}
}
Circle area = 12.57
Rectangle area = 12.00
Circle area = 3.14
Total area = 27.71
The variable type is Shape, but Java calls the area() of the real object. This is called dynamic method dispatch, decided when the program runs. We can add a new shape later and this loop does not change.
Compile time and run time polymorphism
| Kind | Also called | How |
|---|---|---|
| Compile time | Static | Method overloading: chosen by the compiler from the parameters |
| Run time | Dynamic | Method overriding: chosen by the JVM from the real object |
instanceof and casting
A parent reference can only use the methods of the parent. To use a child method, check the type and cast:
class Animal { }
class Dog extends Animal {
void bark() { System.out.println("Woof!"); }
}
class Cat extends Animal { }
public class Cast {
public static void main(String[] args) {
Animal a = new Dog();
// a.bark(); // error: Animal has no bark()
if (a instanceof Dog) {
Dog d = (Dog) a;
d.bark();
}
Animal b = new Cat();
if (b instanceof Dog) {
System.out.println("dog");
} else {
System.out.println("not a dog");
}
}
}
Woof!
not a dog
A wrong cast throws a ClassCastException:
class Animal { }
class Dog extends Animal { }
class Cat extends Animal { }
public class Wrong {
public static void main(String[] args) {
Animal a = new Cat();
Dog d = (Dog) a;
}
}
Exception in thread "main" java.lang.ClassCastException: class Cat cannot be cast to class Dog (Cat and Dog are in unnamed module of loader com.sun.tools.javac.launcher.MemoryClassLoader @4cf4d528)
at Wrong.main(Wrong.java:8)
Pattern matching for instanceof (Java 16+)
The check and the cast can be done in one step:
class Animal { }
class Dog extends Animal {
void bark() { System.out.println("Woof!"); }
}
public class Pattern {
public static void main(String[] args) {
Animal a = new Dog();
if (a instanceof Dog d) { // d is ready to use
d.bark();
}
}
}
Woof!
Fields are not polymorphic
Only methods are overridden. Fields are chosen by the variable type, not by the object. This is a common interview question, so remember it.
| Exercises & Assignments |
|---|
| No Content Found. |
| Interview Questions & Answers |
|---|
| No Content Found. |