Java OOP
Polymorphism
Complete lesson for Polymorphism using LEARNCODEGURU’s 6-level learning model — from basics to advanced practice, with Java OOP and Collections where relevant.
Basics — Polymorphism
Section: Java OOP. Compile-time overloading vs runtime overriding: the heart of Java OOP interviews.
One name, many forms
- **Compile-time (static) polymorphism:** overloading — the compiler picks the method from the *argument types* and *reference type*.
- **Runtime (dynamic) polymorphism:** overriding — the JVM picks the method from the *actual object* (
virtualdispatch). - Upcast:
Animal a = new Dog();The compile-time type isAnimal; the runtime type isDog.
class Payment {
void pay(int amount) {
System.out.println("pay " + amount);
}
}
class Upi extends Payment {
@Override
void pay(int amount) {
System.out.println("UPI " + amount);
}
}
public class PolyDemo {
public static void main(String[] args) {
Payment p = new Upi();
p.pay(99); // UPI 99 — runtime type wins
}
} Overload vs override
| Overload | Override | |
|---|---|---|
| Binding | Compile time | Runtime |
| Signature | Name same, params differ | Name + params same (erasure) |
| Return | Can differ (not only that) | Same or covariant |
| Static / private / final | Can overload | Cannot override these |
| Access | Independent | Cannot be more restrictive |
| Exceptions | Independent | Cannot add new checked exceptions |
@Override and covariant returns
@Overrideis optional but should be mandatory in your style. It catchesequals(Payment)when you meantequals(Object).- A subclass may return a more specific type (
Animal copy()→Dog copy()).
Advanced — Polymorphism
What is not polymorphic
- Fields are not overridden — they are hidden.
super.xvs subclassxdepends on the *reference* type. - Static methods are hidden, not overridden.
Parent ref = new Child(); ref.staticM();callsParent.staticM. privatemethods are not visible to subclasses, so they are not overridden; a subclass method with the same name is unrelated.- Downcast (
(Dog) a) fails withClassCastExceptionif the runtime type is wrong. Preferinstanceof(pattern matching on Java 16+).
Tricky Interview Points
Q1) What is polymorphism in Java?
Answer The ability to treat objects through a common type. Overloading is compile-time; overriding is runtime dispatch on the actual class.
Q2) Why does Payment p = new Upi(); p.pay() call Upi?
Answer pay is an instance method. The JVM looks up the method in the runtime class (Upi), not the reference type (Payment).
Q3) Can you override a static method?
Answer No. You hide it. Which method runs depends on the compile-time type.
Q4) Rules for a valid override?
Answer Same name and parameters, covariant return allowed, same or weaker access restriction, no new checked exceptions, not static/final/private.
Q5) What is covariant return type?
Answer The override may return a subtype of the original return type.
Q6) Is operator overloading polymorphism in Java?
Answer Java does not allow user-defined operator overloading. + for String is built in.
Simple Programs
Array of superclass references
abstract class Notify {
abstract void send(String msg);
}
class Email extends Notify {
@Override
void send(String msg) {
System.out.println("email: " + msg);
}
}
class Sms extends Notify {
@Override
void send(String msg) {
System.out.println("sms: " + msg);
}
}
public class NotifyAll {
public static void main(String[] args) {
Notify[] channels = {new Email(), new Sms()};
for (Notify n : channels) {
n.send("OTP 4412");
}
}
} Problem Solving Tricks
- Always
@Override. It is the cheapest interview-quality habit. - Program to the superclass/interface, construct the concrete class.
- Do not override
equalswithouthashCode. - If you need the subclass extra methods, you probably should not have upcast — or those methods belong on the parent/interface.
Practice Programs List
- Create
Instrumentwithplay()and two subclasses; store them in anInstrument[]. - Overload
play(int times)in one subclass and show that anInstrumentreference cannot see the overload. - Hide a static method and print which version runs from parent vs child references.
- Hide a field
int xand printparentRef.xvs((Child) parentRef).x. - Write
equals/hashCodefor aMoneyclass and put it in aHashSet.