Careeroza
Runtime Polymorphism
Dynamic Method Dispatch
A parent-type variable can hold a child object. When you call an overridden method, the JVM looks at the actual object at runtime, not the variable type.
Example
public class Main {
public static void main(String[] args) {
Shape[] shapes = { new Circle(1), new Rectangle(2, 3), new Circle(2) };
double total = 0;
for (Shape s : shapes) {
System.out.printf("%-10s area = %.2f%n", s.name(), s.area());
total += s.area();
}
System.out.printf("Total area = %.2f%n", total);
}
}
class Shape {
double area() { return 0; }
String name() { return "Shape"; }
}
class Circle extends Shape {
double r;
Circle(double r) { this.r = r; }
@Override double area() { return Math.PI * r * r; }
@Override String name() { return "Circle"; }
}
class Rectangle extends Shape {
double w, h;
Rectangle(double w, double h) { this.w = w; this.h = h; }
@Override double area() { return w * h; }
@Override String name() { return "Rectangle"; }
}Output
Circle area = 3.14 Rectangle area = 6.00 Circle area = 12.57 Total area = 21.71
Fields Are Not Polymorphic
Example
Only methods are dispatched at runtime. Fields and static methods are resolved from the variable type.
public class Main {
public static void main(String[] args) {
Parent p = new Child();
System.out.println(p.name); // field: variable type (Parent)
System.out.println(p.getName()); // method: object type (Child)
p.hello(); // static: variable type (Parent)
}
}
class Parent {
String name = "parent";
String getName() { return name; }
static void hello() { System.out.println("static hello from Parent"); }
}
class Child extends Parent {
String name = "child";
@Override String getName() { return name; }
static void hello() { System.out.println("static hello from Child"); }
}Output
parent child static hello from Parent
Tip: This is a favourite interview trick question. Avoid declaring a field with the same name in parent and child in real code.