Variables/fields are not overridden → they are hidden if re-declared in a subclass.
In upcasting:
Field used = decided by reference type.
Method executed = decided by object type.
Simple Example
class Super { int x = 100; }
class Sub extends Super { int x = 200; // Variable Hiding }
RBI / SBI Example
class RBI { protected String ifscCode = "RBIHYD0001";
public String loan() { return "Provide the loan to customer"; } }class SBI extends RBI { protected String ifscCode = "SBIHYD00045"; // Variable Hiding @Override public String loan() { return "Providing loan @ 9.25% ROI"; } }public class VariableHidingDemo { public static void main(String[] args) { RBI rbi = new SBI(); // Upcasting System.out.println(rbi.ifscCode + " : " + rbi.loan()); } }
Output:
ifscCode → from RBI (RBIHYD0001) because reference type = RBI
loan() → from SBI (Providing loan @ 9.25% ROI) because the object is SBI
7. this vs super In Overriding (Tank Capacity IQ)
class Vehicle { public int tankCapacity() { return 80; }
public void printTankCapacity() { System.out.println(this.tankCapacity()); } }class Car extends Vehicle { @Override public int tankCapacity() { return 40; } public void printTankCapacity() { // If we comment this method → output is 40 System.out.println(super.tankCapacity()); } }public class IQ { public static void main(String[] args) { Vehicle vehicle = new Car(); vehicle.printTankCapacity(); } }
Inside it, this.tankCapacity() → object is Car → output 40
With the overriding printTankCapacity() in Car:
super.tankCapacity() → calls parent (Vehicle) version → output 80
Remember
this → current object’s version (after overriding).
super → immediate parent class version.
8. Can We Override a Private Method?
No.
private Methods are not visible to subclasses → they cannot be overridden.
If a subclass declares a method with the same name + parameters, it is method re-declaration, not overriding.
Because of this, we cannot use @Override such a method.
class Super { private void m1() { System.out.println("M1 method in super class"); } }
class Sub extends Super { public void m1() { // Not overriding, just a new method System.out.println("M1 method in Sub class"); } }public class MethodAccessibility { public static void main(String[] args) { new Sub().m1(); // Calls Sub version only } }
9. Role of Access Modifier While Overriding
Rule
When overriding, we cannot reduce the visibility of the method.
If we try, compiler error → “cannot reduce the visibility of the inherited method”.
Get Aman Verma’s stories in your inbox
Join Medium for free to get updates from this writer.
Visibility Order (low → high)
private < default < protected < public
Allowed Changes
Super class method Sub class method (allowed)defaultdefault, protected, publicprotectedprotected, publicpublicpublic only (cannot become protected/default/private)
10. Polymorphic Behaviour of Method (Using Overriding)
Case 1 — Normal Runtime Polymorphism
class Animal { public void sleep() { System.out.println("Generic Animal is sleeping"); } }
class Dog extends Animal { public void sleep() { System.out.println("Dog Animal is sleeping"); } }class Lion extends Animal { public void sleep() { System.out.println("Lion Animal is sleeping"); } }public class PolymorphicBehavior { public static void main(String[] args) { Animal a1; a1 = new Dog(); executeAnimal(a1); // Dog version System.out.println("--------"); a1 = new Lion(); executeAnimal(a1); // Lion version } public static void executeAnimal(Animal animal) { animal.sleep(); // Dynamic Method Dispatch } }
Case 2 — Need for Downcasting for Specific Methods
class Dog extends Animal { public void sleep() { System.out.println("Dog Animal is sleeping"); } public void bark() { System.out.println("Dog is barking"); } }
class Lion extends Animal { public void sleep() { System.out.println("Lion Animal is sleeping"); } public void roar() { System.out.println("Lion is roaring"); } }public class PolymorphicBehavior { public static void main(String[] args) { Animal a1 = new Dog(); executeAnimal(a1); } public static void executeAnimal(Animal animal) { Dog dog = (Dog) animal; // Downcasting dog.sleep(); dog.bark(); } }
Upcasting Animal a1 = new Dog(); Let's use polymorphism.
But to call bark() (only in Dog), we must downcast to Dog.
Case 3 — Safe Downcasting Using instanceof
public static void executeAnimal(Animal animal) { if (animal instanceof Dog) { Dog dog = (Dog) animal; // old style dog.sleep(); dog.bark(); } else if (animal instanceof Lion lion) { // Java 16 pattern matching lion.sleep(); lion.roar(); } }
instanceof checks real object type before casting → avoids ClassCastException.
11. Polymorphism with instanceof – Payment Example
class Payment { public double makePayment(double amount) { return 0.0; } }
class CreditCard extends Payment { @Override public double makePayment(double amount) { return amount; } public void offer() { System.out.println("Make a payment through credit card and get 2 days holiday package in GOA"); } }class DebitCard extends Payment { @Override public double makePayment(double amount) { return amount; } public void offer() { System.out.println("Make a payment through debit card"); } }class UPI extends Payment { @Override public double makePayment(double amount) { return amount; } public void offer() { System.out.println("Make a payment through UPI and get 1000 Rs cash back"); } }
public class PolymorphicBehavior { public static void main(String[] args) { Payment p = null;
p = new CreditCard(); paymentGateway(p); System.out.println("............."); p = new DebitCard(); paymentGateway(p); System.out.println("............."); p = new UPI(); paymentGateway(p); } public static void paymentGateway(Payment payment) { if (payment instanceof CreditCard card) { double amount = card.makePayment(25000); System.out.println("Making a payment of " + amount + " through Credit Card"); card.offer(); } else if (payment instanceof DebitCard card) { double amount = card.makePayment(12000); System.out.println("Making a payment of " + amount + " through debit Card"); card.offer(); } else if (payment instanceof UPI upi) { double amount = upi.makePayment(30000); System.out.println("Making a payment of " + amount + " through UPI"); upi.offer(); } } }
paymentGateway() parameter type = Payment (superclass).
At runtime, using instanceof, it:
Finds actual subtype (CreditCard, DebitCard, UPI),
Calls overridden makePayment() and its own offer().