Practice Questions — Polymorphism in Java
← Back to NotesTopic-Specific Questions
Question 1
Easy
What is the output of the following code?
class Animal {
void sound() { System.out.println("Animal sound"); }
}
class Dog extends Animal {
void sound() { System.out.println("Bark"); }
}
public class Main {
public static void main(String[] args) {
Animal a = new Dog();
a.sound();
}
}The reference type is Animal, but the actual object is Dog. Which sound() runs?
BarkQuestion 2
Easy
What is the output?
class Calc {
int add(int a, int b) { return a + b; }
double add(double a, double b) { return a + b; }
}
public class Main {
public static void main(String[] args) {
Calc c = new Calc();
System.out.println(c.add(3, 4));
System.out.println(c.add(3.0, 4.0));
}
}The compiler selects the matching method based on argument types.
77.0Question 3
Easy
What is the output?
class A {
void show() { System.out.println("A"); }
}
class B extends A {
void show() { System.out.println("B"); }
}
class C extends B {
void show() { System.out.println("C"); }
}
public class Main {
public static void main(String[] args) {
A obj = new C();
obj.show();
}
}C extends B extends A. The actual object is C.
CQuestion 4
Easy
What is the output?
class Parent {
void greet() { System.out.println("Hello from Parent"); }
}
class Child extends Parent {
}
public class Main {
public static void main(String[] args) {
Parent p = new Child();
p.greet();
}
}Child does not override greet(). What happens?
Hello from ParentQuestion 5
Easy
What is the output?
class Demo {
void print(int a) { System.out.println("int: " + a); }
void print(String a) { System.out.println("String: " + a); }
}
public class Main {
public static void main(String[] args) {
Demo d = new Demo();
d.print(10);
d.print("Arjun");
}
}Method overloading: the compiler picks by argument type.
int: 10String: ArjunQuestion 6
Medium
What is the output?
class Vehicle {
void start() { System.out.println("Vehicle"); }
}
class Car extends Vehicle {
void start() { System.out.println("Car"); }
void openTrunk() { System.out.println("Trunk opened"); }
}
public class Main {
public static void main(String[] args) {
Vehicle v = new Car();
v.start();
System.out.println(v instanceof Car);
System.out.println(v instanceof Vehicle);
}
}instanceof checks the actual object type, not the reference type.
CartruetrueQuestion 7
Medium
What is the output?
class Base {
int x = 10;
void show() { System.out.println(x); }
}
class Derived extends Base {
int x = 20;
void show() { System.out.println(x); }
}
public class Main {
public static void main(String[] args) {
Base b = new Derived();
System.out.println(b.x);
b.show();
}
}Fields are resolved at compile time (by reference type). Methods are resolved at runtime (by object type).
1020Question 8
Medium
What is the output?
class A {
void show(int a) { System.out.println("A-int: " + a); }
}
class B extends A {
void show(int a) { System.out.println("B-int: " + a); }
void show(String a) { System.out.println("B-String: " + a); }
}
public class Main {
public static void main(String[] args) {
A obj = new B();
obj.show(5);
}
}The reference type is A. Which methods can A see?
B-int: 5Question 9
Medium
What is the output?
class Parent {
static void display() { System.out.println("Parent static"); }
void show() { System.out.println("Parent instance"); }
}
class Child extends Parent {
static void display() { System.out.println("Child static"); }
void show() { System.out.println("Child instance"); }
}
public class Main {
public static void main(String[] args) {
Parent p = new Child();
p.display();
p.show();
}
}Static methods are resolved by reference type. Instance methods are resolved by object type.
Parent staticChild instanceQuestion 10
Medium
What is the output?
class Printer {
void print(Object o) { System.out.println("Object: " + o); }
void print(String s) { System.out.println("String: " + s); }
void print(int i) { System.out.println("int: " + i); }
}
public class Main {
public static void main(String[] args) {
Printer p = new Printer();
p.print("Hello");
p.print(42);
p.print((Object) "World");
}
}Overloading is resolved at compile time based on the compile-time type of arguments.
String: Helloint: 42Object: WorldQuestion 11
Medium
What is the output?
class Shape {
void draw() { System.out.println("Shape"); }
}
class Circle extends Shape {
void draw() { System.out.println("Circle"); }
}
class ColoredCircle extends Circle {
void draw() { System.out.println("Colored Circle"); }
}
public class Main {
public static void main(String[] args) {
Shape s1 = new Circle();
Shape s2 = new ColoredCircle();
Circle c1 = new ColoredCircle();
s1.draw();
s2.draw();
c1.draw();
}
}Each call resolves to the actual object type's draw() method.
CircleColored CircleColored CircleQuestion 12
Hard
What is the output?
class A {
void method() { System.out.println("A.method"); }
}
class B extends A {
void method() { System.out.println("B.method"); }
}
class C extends A {
void method() { System.out.println("C.method"); }
}
public class Main {
public static void main(String[] args) {
A[] arr = { new A(), new B(), new C(), new B() };
for (A a : arr) {
a.method();
}
}
}Each element in the array is a different actual type.
A.methodB.methodC.methodB.methodQuestion 13
Hard
What is the output?
class Parent {
int value() { return 10; }
void print() { System.out.println(value()); }
}
class Child extends Parent {
int value() { return 20; }
}
public class Main {
public static void main(String[] args) {
Parent p = new Child();
p.print();
}
}print() is inherited by Child. But value() is overridden. Which value() does print() call?
20Question 14
Hard
What is the output?
class Base {
void display(int a) { System.out.println("Base-int"); }
void display(double a) { System.out.println("Base-double"); }
}
class Child extends Base {
void display(int a) { System.out.println("Child-int"); }
}
public class Main {
public static void main(String[] args) {
Base b = new Child();
b.display(10);
b.display(10.5);
}
}Child only overrides display(int). display(double) is inherited.
Child-intBase-doubleQuestion 15
Hard
What is the output?
class A {
A get() {
System.out.println("A's get");
return this;
}
}
class B extends A {
B get() {
System.out.println("B's get");
return this;
}
}
public class Main {
public static void main(String[] args) {
A obj = new B();
obj.get();
}
}B's get() returns B instead of A. Is this a valid override?
B's getQuestion 16
Hard
What is the output?
class Animal {
Animal() { System.out.println("Animal constructor"); }
void eat() { System.out.println("Animal eats"); }
}
class Dog extends Animal {
Dog() { System.out.println("Dog constructor"); }
void eat() { System.out.println("Dog eats"); }
void bark() { System.out.println("Dog barks"); }
}
public class Main {
public static void main(String[] args) {
Animal a = new Dog();
a.eat();
System.out.println(a instanceof Animal);
System.out.println(a instanceof Dog);
}
}Constructors run during object creation. Then polymorphic method call. Then instanceof checks.
Animal constructorDog constructorDog eatstruetrueQuestion 17
Hard
What is the output?
class X {
void method(X x) { System.out.println("X-X"); }
void method(Y y) { System.out.println("X-Y"); }
}
class Y extends X {
void method(X x) { System.out.println("Y-X"); }
void method(Y y) { System.out.println("Y-Y"); }
}
public class Main {
public static void main(String[] args) {
X obj = new Y();
obj.method(new Y());
}
}Overloading is resolved at compile time (reference types). Overriding is resolved at runtime.
Y-YQuestion 18
Hard
What is the output?
class Base {
void show() {
System.out.println("Base show");
display();
}
void display() {
System.out.println("Base display");
}
}
class Derived extends Base {
void display() {
System.out.println("Derived display");
}
}
public class Main {
public static void main(String[] args) {
Base b = new Derived();
b.show();
}
}show() is not overridden, but it calls display() which IS overridden.
Base showDerived displayMixed & Application Questions
Question 1
Easy
What is the output?
class Greet {
void hello(String name) { System.out.println("Hello, " + name); }
void hello(String name, int times) {
for (int i = 0; i < times; i++) {
System.out.println("Hi, " + name);
}
}
}
public class Main {
public static void main(String[] args) {
Greet g = new Greet();
g.hello("Kavya");
g.hello("Ravi", 2);
}
}Two overloaded methods with different parameter counts.
Hello, KavyaHi, RaviHi, RaviQuestion 2
Easy
What is the output?
class Animal {
String type = "Animal";
void identify() { System.out.println(type); }
}
class Cat extends Animal {
String type = "Cat";
void identify() { System.out.println(type); }
}
public class Main {
public static void main(String[] args) {
Cat c = new Cat();
c.identify();
System.out.println(c.type);
}
}When using the actual type as reference, no polymorphism ambiguity arises.
CatCatQuestion 3
Medium
What is the output?
class Num {
void show(int a) { System.out.println("int"); }
void show(long a) { System.out.println("long"); }
void show(float a) { System.out.println("float"); }
void show(double a) { System.out.println("double"); }
}
public class Main {
public static void main(String[] args) {
Num n = new Num();
byte b = 5;
n.show(b);
n.show(5L);
n.show(5.0f);
n.show(5.0);
}
}byte is promoted to int (smallest compatible type).
intlongfloatdoubleQuestion 4
Medium
What is the output?
class Parent {
void show() { System.out.println("Parent"); }
}
class ChildA extends Parent {
void show() { System.out.println("ChildA"); }
}
class ChildB extends Parent {
void show() { System.out.println("ChildB"); }
}
public class Main {
static void display(Parent p) { p.show(); }
public static void main(String[] args) {
display(new Parent());
display(new ChildA());
display(new ChildB());
}
}The display method accepts Parent but receives different subtypes.
ParentChildAChildBQuestion 5
Easy
What is the difference between compile-time polymorphism and runtime polymorphism?
Think about when the decision is made: during compilation or during execution.
Compile-time polymorphism (method overloading) is resolved by the compiler based on argument types and count. Runtime polymorphism (method overriding) is resolved by the JVM at runtime based on the actual object type. Overloading is within the same class; overriding is across parent-child classes.
Question 6
Medium
What is the output?
class A {
void test(Object o) { System.out.println("Object"); }
void test(String s) { System.out.println("String"); }
}
public class Main {
public static void main(String[] args) {
A a = new A();
a.test(null);
}
}null can match both Object and String. Which is more specific?
StringQuestion 7
Hard
What is the output?
class A {
int x = 10;
void show() { System.out.println("A: " + x); }
}
class B extends A {
int x = 20;
}
public class Main {
public static void main(String[] args) {
A obj = new B();
System.out.println(obj.x);
obj.show();
}
}B does not override show(). Fields are not polymorphic.
10A: 10Question 8
Medium
Can we override a
private method in Java?Private methods are not visible to subclasses.
No, private methods cannot be overridden. They are not visible to subclasses. If a subclass defines a method with the same name and parameters as a parent's private method, it is a completely new method, not an override.
Question 9
Hard
What is the output?
class Base {
Base() {
System.out.println("Base constructor");
show();
}
void show() { System.out.println("Base show"); }
}
class Child extends Base {
int x = 10;
Child() {
System.out.println("Child constructor, x=" + x);
}
void show() { System.out.println("Child show, x=" + x); }
}
public class Main {
public static void main(String[] args) {
Child c = new Child();
}
}The Base constructor runs first. It calls show(). Which show() runs? What is x at that point?
Base constructorChild show, x=0Child constructor, x=10Question 10
Hard
What is the output?
class Animal {
void eat() { System.out.println("Animal eats"); }
}
class Dog extends Animal {
void eat() { System.out.println("Dog eats"); }
void bark() { System.out.println("Dog barks"); }
}
public class Main {
public static void main(String[] args) {
Animal a = new Dog();
a.eat();
Dog d = (Dog) a;
d.eat();
d.bark();
Animal a2 = (Animal) d;
a2.eat();
}
}All references point to the same Dog object. Casting does not change the object.
Dog eatsDog eatsDog barksDog eatsQuestion 11
Medium
What is the difference between method hiding and method overriding?
One involves static methods, the other involves instance methods.
Method overriding applies to instance methods and uses dynamic dispatch (runtime resolution based on object type). Method hiding applies to static methods, where the child class defines a static method with the same signature. Static methods are resolved by the reference type at compile time, not the object type.
Question 12
Hard
What is the output?
class A {
void method() { System.out.println("A"); }
}
class B extends A {
void method() { System.out.println("B"); }
}
class C extends B {
void method() { System.out.println("C"); }
}
public class Main {
public static void main(String[] args) {
A obj = new C();
System.out.println(obj instanceof A);
System.out.println(obj instanceof B);
System.out.println(obj instanceof C);
System.out.println(obj instanceof Object);
}
}instanceof checks if the object IS-A certain type (including all ancestors).
truetruetruetrueMultiple Choice Questions
MCQ 1
What is polymorphism in Java?
Answer: B
B is correct. Polymorphism literally means 'many forms.' In Java, it refers to methods or references that can behave differently based on the context (argument types, actual object type).
B is correct. Polymorphism literally means 'many forms.' In Java, it refers to methods or references that can behave differently based on the context (argument types, actual object type).
MCQ 2
Which of the following is compile-time polymorphism?
Answer: B
B is correct. Method overloading is resolved at compile time based on argument types and count. Method overriding and dynamic dispatch are runtime polymorphism.
B is correct. Method overloading is resolved at compile time based on argument types and count. Method overriding and dynamic dispatch are runtime polymorphism.
MCQ 3
What is required for method overloading?
Answer: B
B is correct. Overloaded methods must have different parameter lists (number, type, or order of parameters). Return type alone does not qualify as overloading.
B is correct. Overloaded methods must have different parameter lists (number, type, or order of parameters). Return type alone does not qualify as overloading.
MCQ 4
What is upcasting in Java?
Answer: B
B is correct. Upcasting is assigning a child class object to a parent class reference:
B is correct. Upcasting is assigning a child class object to a parent class reference:
Animal a = new Dog();. It is implicit and always safe.MCQ 5
What annotation should you use when overriding a method?
Answer: B
B is correct. The
B is correct. The
@Override annotation is recommended (but not mandatory) when overriding a method. It causes a compile-time error if the method does not actually override a parent method, catching mistakes early.MCQ 6
What is dynamic method dispatch?
Answer: B
B is correct. Dynamic method dispatch is the mechanism where the JVM determines at runtime which overridden method to call, based on the actual object type rather than the reference type.
B is correct. Dynamic method dispatch is the mechanism where the JVM determines at runtime which overridden method to call, based on the actual object type rather than the reference type.
MCQ 7
Which of these CANNOT be overridden in Java?
Answer: C
C is correct. Static methods belong to the class, not instances. They cannot be overridden, only hidden. Public, protected, and default methods can all be overridden (assuming visibility).
C is correct. Static methods belong to the class, not instances. They cannot be overridden, only hidden. Public, protected, and default methods can all be overridden (assuming visibility).
MCQ 8
What happens when you downcast without checking instanceof?
Answer: C
C is correct. Downcasting compiles successfully (the compiler trusts you). But at runtime, if the actual object is not compatible with the target type, the JVM throws
C is correct. Downcasting compiles successfully (the compiler trusts you). But at runtime, if the actual object is not compatible with the target type, the JVM throws
ClassCastException.MCQ 9
What is a covariant return type?
Answer: C
C is correct. A covariant return type allows the overriding method to return a subtype of the parent method's return type. For example, if the parent returns
C is correct. A covariant return type allows the overriding method to return a subtype of the parent method's return type. For example, if the parent returns
Number, the child can return Integer.MCQ 10
In
Parent p = new Child();, which class determines the methods that can be called?Answer: B
B is correct. The reference type (
B is correct. The reference type (
Parent) determines which methods can be called (compilation check). The actual object type (Child) determines which version of an overridden method runs (runtime dispatch).MCQ 11
Are fields (instance variables) polymorphic in Java?
Answer: B
B is correct. Fields are NOT polymorphic. They are resolved at compile time based on the reference type. Only instance methods support runtime polymorphism through dynamic dispatch.
B is correct. Fields are NOT polymorphic. They are resolved at compile time based on the reference type. Only instance methods support runtime polymorphism through dynamic dispatch.
MCQ 12
What is the output?
class A { void m(A a) { System.out.println("AA"); } }
class B extends A { void m(B b) { System.out.println("BB"); } }
A obj = new B(); obj.m(new B());Answer: A
A is correct.
A is correct.
B's m(B) does not override A's m(A) (different parameter type). It is an overloaded method. The reference type A only sees m(A). The argument new B() matches m(A) via upcasting. Since B does not override m(A), the inherited A's version runs.MCQ 13
Which is true about the
instanceof operator?Answer: B
B is correct.
B is correct.
instanceof checks the actual object type against the specified class/interface, including all parent classes and implemented interfaces. It returns false for null (no exception).MCQ 14
Why is calling an overridable method from a constructor considered bad practice?
Answer: B
B is correct. When a parent constructor calls an overridable method, the child's overriding version runs (dynamic dispatch). But the child's constructor has not executed yet, so the child's fields are still at default values (0, null, false). This can lead to subtle bugs.
B is correct. When a parent constructor calls an overridable method, the child's overriding version runs (dynamic dispatch). But the child's constructor has not executed yet, so the child's fields are still at default values (0, null, false). This can lead to subtle bugs.
MCQ 15
What happens if an overriding method has a MORE restrictive access modifier?
Answer: C
C is correct. An overriding method cannot have a more restrictive access modifier than the overridden method. If the parent method is
C is correct. An overriding method cannot have a more restrictive access modifier than the overridden method. If the parent method is
public, the child cannot make it private or protected. This is a compile-time error.Coding Challenges
Challenge 1: Shape Area Calculator
EasyCreate a base class Shape with a method area() returning 0. Create subclasses Circle (takes radius), Rectangle (takes width, height), and Triangle (takes base, height). Override area() in each. Store all three in a Shape array and print each area using a loop.
Sample Input
Circle radius=5, Rectangle 4x6, Triangle base=3 height=8
Sample Output
Circle area: 78.54
Rectangle area: 24.00
Triangle area: 12.00
Use polymorphism with a Shape array. Use @Override annotation.
class Shape {
double area() { return 0; }
String name() { return "Shape"; }
}
class Circle extends Shape {
double radius;
Circle(double r) { this.radius = r; }
@Override double area() { return Math.PI * radius * radius; }
@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"; }
}
class Triangle extends Shape {
double base, height;
Triangle(double b, double h) { this.base = b; this.height = h; }
@Override double area() { return 0.5 * base * height; }
@Override String name() { return "Triangle"; }
}
public class Main {
public static void main(String[] args) {
Shape[] shapes = { new Circle(5), new Rectangle(4, 6), new Triangle(3, 8) };
for (Shape s : shapes) {
System.out.printf("%s area: %.2f%n", s.name(), s.area());
}
}
}Challenge 2: Payment Processor
MediumCreate a base class Payment with a method process(double amount) that prints 'Processing payment of '. Create subclasses CreditCard, UPI, and NetBanking, each overriding process() with their own message. Write a method processAll(Payment[] payments, double amount) that calls process() on each.
Sample Input
Amount = 1500.0
Sample Output
Credit Card: Processing 1500.0 with 2% surcharge
UPI: Processing 1500.0 instantly
Net Banking: Processing 1500.0 via bank transfer
Use an array of Payment references. Demonstrate dynamic dispatch.
class Payment {
void process(double amount) {
System.out.println("Processing payment of " + amount);
}
}
class CreditCard extends Payment {
@Override
void process(double amount) {
System.out.println("Credit Card: Processing " + amount + " with 2% surcharge");
}
}
class UPI extends Payment {
@Override
void process(double amount) {
System.out.println("UPI: Processing " + amount + " instantly");
}
}
class NetBanking extends Payment {
@Override
void process(double amount) {
System.out.println("Net Banking: Processing " + amount + " via bank transfer");
}
}
public class Main {
static void processAll(Payment[] payments, double amount) {
for (Payment p : payments) {
p.process(amount);
}
}
public static void main(String[] args) {
Payment[] payments = { new CreditCard(), new UPI(), new NetBanking() };
processAll(payments, 1500.0);
}
}Challenge 3: Overloaded Calculator
EasyCreate a Calculator class with overloaded multiply methods: multiply(int, int), multiply(int, int, int), multiply(double, double), and multiply(int, double). Test each version.
Sample Input
(No input required)
Sample Output
int x int: 20
int x int x int: 60
double x double: 7.5
int x double: 12.5
All methods should be named multiply. Demonstrate compile-time polymorphism.
class Calculator {
int multiply(int a, int b) { return a * b; }
int multiply(int a, int b, int c) { return a * b * c; }
double multiply(double a, double b) { return a * b; }
double multiply(int a, double b) { return a * b; }
}
public class Main {
public static void main(String[] args) {
Calculator c = new Calculator();
System.out.println("int x int: " + c.multiply(4, 5));
System.out.println("int x int x int: " + c.multiply(3, 4, 5));
System.out.println("double x double: " + c.multiply(2.5, 3.0));
System.out.println("int x double: " + c.multiply(5, 2.5));
}
}Challenge 4: Animal Sound Simulator with instanceof
MediumCreate Animal, Dog, Cat, and Parrot classes. Dog has fetch(), Cat has purr(), Parrot has mimic(). Write a method interact(Animal a) that calls the animal's sound() and then uses instanceof to call the subclass-specific method.
Sample Input
(No input required)
Sample Output
Bark!
Dog fetches ball
---
Meow!
Cat purrs
---
Squawk!
Parrot mimics speech
Use instanceof for safe downcasting. Handle all subtypes.
class Animal {
void sound() { System.out.println("..."); }
}
class Dog extends Animal {
@Override void sound() { System.out.println("Bark!"); }
void fetch() { System.out.println("Dog fetches ball"); }
}
class Cat extends Animal {
@Override void sound() { System.out.println("Meow!"); }
void purr() { System.out.println("Cat purrs"); }
}
class Parrot extends Animal {
@Override void sound() { System.out.println("Squawk!"); }
void mimic() { System.out.println("Parrot mimics speech"); }
}
public class Main {
static void interact(Animal a) {
a.sound();
if (a instanceof Dog) ((Dog) a).fetch();
else if (a instanceof Cat) ((Cat) a).purr();
else if (a instanceof Parrot) ((Parrot) a).mimic();
}
public static void main(String[] args) {
interact(new Dog());
System.out.println("---");
interact(new Cat());
System.out.println("---");
interact(new Parrot());
}
}Challenge 5: Employee Salary System
HardCreate an abstract-like hierarchy: Employee (base, salary()), FullTime (fixed monthly salary), PartTime (hourly rate * hours), and Intern (stipend). Override salary() in each. Create an array of employees and compute total payroll using a loop.
Sample Input
FullTime=50000, PartTime=500/hr*80hrs, Intern=15000
Sample Output
FullTime salary: 50000.0
PartTime salary: 40000.0
Intern salary: 15000.0
Total payroll: 105000.0
Use polymorphism. Compute total using a single loop over Employee[].
class Employee {
String name;
Employee(String name) { this.name = name; }
double salary() { return 0; }
}
class FullTime extends Employee {
double monthly;
FullTime(String name, double monthly) { super(name); this.monthly = monthly; }
@Override double salary() { return monthly; }
}
class PartTime extends Employee {
double rate; int hours;
PartTime(String name, double rate, int hours) { super(name); this.rate = rate; this.hours = hours; }
@Override double salary() { return rate * hours; }
}
class Intern extends Employee {
double stipend;
Intern(String name, double stipend) { super(name); this.stipend = stipend; }
@Override double salary() { return stipend; }
}
public class Main {
public static void main(String[] args) {
Employee[] team = {
new FullTime("Arjun", 50000),
new PartTime("Kavya", 500, 80),
new Intern("Ravi", 15000)
};
double total = 0;
for (Employee e : team) {
System.out.println(e.name + " salary: " + e.salary());
total += e.salary();
}
System.out.println("Total payroll: " + total);
}
}Need to Review the Concepts?
Go back to the detailed notes for this chapter.
Read Chapter NotesWant to learn Java with a live mentor?
Explore our Java Masterclass