Practice Questions — Inheritance 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("Some sound"); }
}
class Dog extends Animal {
void bark() { System.out.println("Woof!"); }
}
Dog d = new Dog();
d.sound();
d.bark();Dog inherits sound() from Animal and has its own bark() method.
Some soundWoof!Question 2
Easy
What is the output?
class A {
int x = 10;
}
class B extends A {
int y = 20;
}
B obj = new B();
System.out.println(obj.x + obj.y);B inherits x from A and has its own y.
30Question 3
Easy
What is the output?
class Parent {
void greet() { System.out.println("Hello from Parent"); }
}
class Child extends Parent {
@Override
void greet() { System.out.println("Hello from Child"); }
}
Child c = new Child();
c.greet();The overridden method in Child replaces the Parent's version.
Hello from ChildQuestion 4
Easy
What is the output?
class A {
A() { System.out.println("A constructor"); }
}
class B extends A {
B() { System.out.println("B constructor"); }
}
B obj = new B();Java automatically calls super() if you do not write it. Parent constructor runs first.
A constructorB constructorQuestion 5
Easy
What is the output?
Dog d = new Dog();
System.out.println(d instanceof Dog);
System.out.println(d instanceof Animal);
System.out.println(d instanceof Object);(Assume Dog extends Animal)
instanceof checks the entire inheritance chain.
truetruetrueQuestion 6
Medium
What is the output?
class Animal {
void eat() { System.out.println("Animal eating"); }
}
class Dog extends Animal {
@Override
void eat() {
super.eat();
System.out.println("Dog eating bones");
}
}
Dog d = new Dog();
d.eat();super.eat() calls the parent's version first, then the child adds its own behavior.
Animal eatingDog eating bonesQuestion 7
Medium
What is the output?
class A {
String type = "A";
}
class B extends A {
String type = "B";
void show() {
System.out.println(this.type);
System.out.println(super.type);
}
}
new B().show();this.type refers to B's field. super.type refers to A's field.
BAQuestion 8
Medium
What is the output?
class A {
A() { System.out.println("A()"); }
A(int x) { System.out.println("A(" + x + ")"); }
}
class B extends A {
B() {
super(10);
System.out.println("B()");
}
}
B obj = new B();super(10) calls A's parameterized constructor, not the no-arg one.
A(10)B()Question 9
Medium
What is the output?
class Animal {
String name;
Animal(String name) { this.name = name; }
public String toString() { return "Animal: " + name; }
}
class Dog extends Animal {
String breed;
Dog(String name, String breed) {
super(name);
this.breed = breed;
}
public String toString() { return "Dog: " + name + " (" + breed + ")"; }
}
Animal a = new Dog("Buddy", "Lab");
System.out.println(a);
System.out.println(a instanceof Dog);The variable type is Animal but the actual object is Dog. Which toString() runs?
Dog: Buddy (Lab)trueQuestion 10
Hard
What is the output?
class A {
A() { System.out.println("A"); }
}
class B extends A {
B() { System.out.println("B"); }
}
class C extends B {
C() { System.out.println("C"); }
}
C obj = new C();Multilevel inheritance: constructors execute from top to bottom.
ABCQuestion 11
Hard
What is the output?
class Parent {
int x = 10;
int getX() { return x; }
}
class Child extends Parent {
int x = 20;
@Override
int getX() { return x; }
}
Parent p = new Child();
System.out.println(p.x);
System.out.println(p.getX());Fields are resolved at compile time (based on reference type). Methods are resolved at runtime (based on object type).
1020Question 12
Hard
What is the output?
class Base {
void display() { System.out.println("Base: " + getValue()); }
int getValue() { return 10; }
}
class Derived extends Base {
@Override
int getValue() { return 20; }
}
Base b = new Derived();
b.display();display() is inherited from Base but calls getValue() which is overridden in Derived.
Base: 20Question 13
Hard
What is the output?
class A {
A() { print(); }
void print() { System.out.println("A"); }
}
class B extends A {
int value = 10;
@Override
void print() { System.out.println("B: " + value); }
}
B obj = new B();A's constructor calls print(). But the actual object is B, so B's print() runs. What is value at that point?
B: 0Mixed & Application Questions
Question 1
Easy
What is the output?
class Vehicle {
int speed = 0;
void accelerate() { speed += 10; }
}
class Car extends Vehicle {
void turbo() { speed += 50; }
}
Car c = new Car();
c.accelerate();
c.turbo();
System.out.println(c.speed);Car inherits speed and accelerate(). Both methods modify the same speed field.
60Question 2
Easy
What is the output?
final int x = 10;
// x = 20; // Would this compile?
System.out.println(x);final variables cannot be reassigned after initialization.
10 (The commented line would cause a compilation error if uncommented)Question 3
Easy
What is the difference between method overloading and method overriding?
One is within a class, the other is between parent and child classes.
Overloading: Same method name, different parameter list, within the same class (or inherited). Resolved at compile time. Overriding: Same method name and parameter list, in a subclass. Replaces the parent's behavior. Resolved at runtime.
Question 4
Medium
What is the output?
class A {
static void hello() { System.out.println("A"); }
}
class B extends A {
static void hello() { System.out.println("B"); }
}
A obj = new B();
obj.hello();Static methods are resolved based on the reference type (compile time), not the object type.
AQuestion 5
Medium
What is the output?
class Shape {
double area() { return 0; }
public String toString() { return "Area: " + area(); }
}
class Circle extends Shape {
double r;
Circle(double r) { this.r = r; }
@Override
double area() { return Math.PI * r * r; }
}
class Square extends Shape {
double side;
Square(double side) { this.side = side; }
@Override
double area() { return side * side; }
}
Shape[] shapes = { new Circle(5), new Square(4) };
for (Shape s : shapes) {
System.out.printf("%.2f%n", s.area());
}Each subclass overrides area(). The correct version is called at runtime.
78.5416.00Question 6
Medium
Why does Java not support multiple inheritance with classes?
Think about the diamond problem.
Java does not support multiple class inheritance to avoid the diamond problem: if a class inherits from two classes that have a method with the same signature, it would be ambiguous which version to call. Java uses interfaces to achieve a form of multiple inheritance without this ambiguity, because interfaces (before Java 8) had no method implementations, and default methods have explicit conflict resolution rules.
Question 7
Hard
What is the output?
class A {
int x = 5;
A() { this.x = 10; }
}
class B extends A {
int x = 20;
B() { this.x = 30; }
}
B obj = new B();
System.out.println(((A) obj).x);
System.out.println(obj.x);Fields are resolved at compile time based on the reference type. A has its own x, B has its own x.
1030Question 8
Hard
What is the output?
class Animal {
void eat() { System.out.println("Animal eat"); }
}
class Dog extends Animal {
@Override
void eat() { System.out.println("Dog eat"); }
void bark() { System.out.println("Woof"); }
}
Animal a = new Dog();
a.eat();
// a.bark(); // Would this compile?The reference type determines what methods can be called. The runtime type determines which overridden version runs.
Dog eat(The commented line would NOT compile:
bark() is not in Animal)Question 9
Hard
What is the contract between equals() and hashCode()? Why must both be overridden together?
Think about how HashMaps use both methods to store and retrieve objects.
The contract states: if two objects are equal according to equals(), they must have the same hashCode(). If you override equals() without hashCode(), objects that are "equal" may be placed in different hash buckets in a HashMap, making them unfindable. If you override hashCode() without equals(), objects with the same hash code may not be considered equal, leading to duplicates.
Multiple Choice Questions
MCQ 1
Which keyword is used to inherit a class in Java?
Answer: C
C is correct. The
C is correct. The
extends keyword is used for class inheritance. implements (A) is for interfaces. inherits (B) is not a Java keyword. super (D) refers to the parent class but does not declare inheritance.MCQ 2
What type of inheritance is NOT supported in Java with classes?
Answer: C
C is correct. Java does not support multiple inheritance with classes — a class can extend only one class. Single (A), multilevel (B), and hierarchical (D) are all supported.
C is correct. Java does not support multiple inheritance with classes — a class can extend only one class. Single (A), multilevel (B), and hierarchical (D) are all supported.
MCQ 3
What does the @Override annotation do?
Answer: B
B is correct.
B is correct.
@Override is optional but causes the compiler to verify that the method signature matches a superclass method. If it does not match (typo in name or wrong parameters), the compiler reports an error. It is not required (A), does not prevent further overriding (C — that is final), and does not change access (D).MCQ 4
If class B extends class A, which constructor runs first when creating a B object?
Answer: B
B is correct (more precisely, C runs before B, and B runs before the current class). The chain is Object -> A -> B. Among the listed options, A's constructor runs before B's. The superclass is always initialized before the subclass.
B is correct (more precisely, C runs before B, and B runs before the current class). The chain is Object -> A -> B. Among the listed options, A's constructor runs before B's. The superclass is always initialized before the subclass.
MCQ 5
Which of the following can be overridden?
Answer: D
D is correct. Only non-static, non-final, non-private instance methods can be overridden. Static methods (A) are hidden, not overridden. Final methods (B) cannot be overridden by definition. Private methods (C) are not visible to subclasses.
D is correct. Only non-static, non-final, non-private instance methods can be overridden. Static methods (A) are hidden, not overridden. Final methods (B) cannot be overridden by definition. Private methods (C) are not visible to subclasses.
MCQ 6
What happens if you do not call super() in a subclass constructor?
Answer: B
B is correct. If you do not explicitly call
B is correct. If you do not explicitly call
super() or this(), Java inserts super() (no-arg) as the first statement. This only causes an error if the superclass does not have a no-arg constructor.MCQ 7
What is a covariant return type?
Answer: B
B is correct. Covariant return types allow an overriding method to return a more specific type. If the parent returns
B is correct. Covariant return types allow an overriding method to return a more specific type. If the parent returns
Animal, the child can return Dog (since Dog IS-A Animal). This avoids casting at the call site.MCQ 8
What does instanceof return when the object is null?
Answer: B
B is correct.
B is correct.
null instanceof AnyType always returns false. No exception is thrown. This makes instanceof safe to use without null checks.MCQ 9
Can a final class have final methods?
Answer: A
A is correct. A final class cannot be extended, so no subclass exists to override any of its methods. Making methods final in a final class is syntactically valid but redundant — there is no subclass to prevent overriding in.
A is correct. A final class cannot be extended, so no subclass exists to override any of its methods. Making methods final in a final class is syntactically valid but redundant — there is no subclass to prevent overriding in.
MCQ 10
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"); }
}
A obj = new C();
obj.show();Answer: C
C is correct. The actual object is C, and C overrides
C is correct. The actual object is C, and C overrides
show(). Method resolution at runtime uses the actual type (C), so C's version runs. The reference type (A) only determines what methods can be called, not which version runs.MCQ 11
Which of the following is true about calling super() and this() in a constructor?
Answer: B
B is correct. Both
B is correct. Both
super() and this() must be the first statement in a constructor. Since only one statement can be first, you cannot have both in the same constructor. You choose super() to call a parent constructor or this() to chain to another constructor in the same class.MCQ 12
What is the relationship between fields and inheritance in Java?
Answer: B
B is correct. When a subclass declares a field with the same name as a superclass field, it hides the parent's field (both coexist). This is different from method overriding. The parent's field is accessed via
B is correct. When a subclass declares a field with the same name as a superclass field, it hides the parent's field (both coexist). This is different from method overriding. The parent's field is accessed via
super.fieldName or through a parent-type reference. Fields are resolved at compile time by declared type.MCQ 13
Which Object method should you always override together with equals()?
Answer: B
B is correct. The equals-hashCode contract requires that equal objects have equal hash codes. If you override equals() without hashCode(), hash-based collections (HashMap, HashSet) will malfunction. toString() (A) should also be overridden but is not part of the equals contract.
B is correct. The equals-hashCode contract requires that equal objects have equal hash codes. If you override equals() without hashCode(), hash-based collections (HashMap, HashSet) will malfunction. toString() (A) should also be overridden but is not part of the equals contract.
Coding Challenges
Challenge 1: Shape Hierarchy with Area Calculation
EasyCreate a Shape class with a method area() that returns 0. Create Circle (with radius) and Rectangle (with width and height) subclasses that override area(). Create objects and print their areas.
Sample Input
(No input required)
Sample Output
Circle area: 78.54
Rectangle area: 24.00
Use inheritance and method overriding. Format output to 2 decimal places.
class Shape {
double area() { return 0; }
}
class Circle extends Shape {
double radius;
Circle(double radius) { this.radius = radius; }
@Override
double area() { return Math.PI * radius * radius; }
}
class Rectangle extends Shape {
double width, height;
Rectangle(double width, double height) {
this.width = width;
this.height = height;
}
@Override
double area() { return width * height; }
}
public class Main {
public static void main(String[] args) {
Shape c = new Circle(5);
Shape r = new Rectangle(4, 6);
System.out.printf("Circle area: %.2f%n", c.area());
System.out.printf("Rectangle area: %.2f%n", r.area());
}
}Challenge 2: Animal Sound Polymorphism
EasyCreate an Animal class with a makeSound() method. Create Dog, Cat, and Cow subclasses that override makeSound(). Store them in an Animal array and call makeSound() on each using a loop.
Sample Input
(No input required)
Sample Output
Dog says: Woof!
Cat says: Meow!
Cow says: Moo!
Use an Animal array and a for-each loop to demonstrate polymorphism.
class Animal {
String name;
Animal(String name) { this.name = name; }
void makeSound() { System.out.println(name + " says: ..."); }
}
class Dog extends Animal {
Dog() { super("Dog"); }
@Override
void makeSound() { System.out.println(name + " says: Woof!"); }
}
class Cat extends Animal {
Cat() { super("Cat"); }
@Override
void makeSound() { System.out.println(name + " says: Meow!"); }
}
class Cow extends Animal {
Cow() { super("Cow"); }
@Override
void makeSound() { System.out.println(name + " says: Moo!"); }
}
public class Main {
public static void main(String[] args) {
Animal[] animals = { new Dog(), new Cat(), new Cow() };
for (Animal a : animals) {
a.makeSound();
}
}
}Challenge 3: Employee Payroll System
MediumCreate an Employee class with name and baseSalary. Create Manager (with bonus) and Developer (with overtimeHours at Rs.500/hr) subclasses. Override a calculatePay() method. Print payroll for all employees.
Sample Input
(No input required)
Sample Output
Kavitha (Manager): Rs.95000.0
Rohan (Developer): Rs.70000.0
Deepak (Developer): Rs.62500.0
Use super.calculatePay() to avoid duplicating base salary logic.
class Employee {
String name;
double baseSalary;
Employee(String name, double baseSalary) {
this.name = name;
this.baseSalary = baseSalary;
}
double calculatePay() { return baseSalary; }
}
class Manager extends Employee {
double bonus;
Manager(String name, double baseSalary, double bonus) {
super(name, baseSalary);
this.bonus = bonus;
}
@Override
double calculatePay() { return super.calculatePay() + bonus; }
}
class Developer extends Employee {
int overtimeHours;
Developer(String name, double baseSalary, int overtimeHours) {
super(name, baseSalary);
this.overtimeHours = overtimeHours;
}
@Override
double calculatePay() { return super.calculatePay() + overtimeHours * 500; }
}
public class Main {
public static void main(String[] args) {
Employee[] team = {
new Manager("Kavitha", 80000, 15000),
new Developer("Rohan", 60000, 20),
new Developer("Deepak", 55000, 15)
};
for (Employee e : team) {
System.out.println(e.name + " (" + e.getClass().getSimpleName() + "): Rs." + e.calculatePay());
}
}
}Challenge 4: Bank Account Hierarchy
MediumCreate a BankAccount class with accountHolder and balance. Create SavingsAccount (with interest rate) and CurrentAccount (with overdraft limit). SavingsAccount has addInterest(). CurrentAccount allows withdrawal beyond balance up to the overdraft limit. Demonstrate both.
Sample Input
(No input required)
Sample Output
Savings - Priya: Rs.10000.0
After interest: Rs.10500.0
Current - Aarav: Rs.5000.0
Withdrew Rs.7000.0 (using overdraft)
Balance: Rs.-2000.0
Use inheritance with super constructors. Override withdraw() in CurrentAccount.
class BankAccount {
String holder;
double balance;
BankAccount(String holder, double balance) {
this.holder = holder;
this.balance = balance;
}
void withdraw(double amount) {
if (amount > balance) {
System.out.println("Insufficient funds");
} else {
balance -= amount;
System.out.println("Withdrew Rs." + amount);
}
}
public String toString() {
return holder + ": Rs." + balance;
}
}
class SavingsAccount extends BankAccount {
double interestRate;
SavingsAccount(String holder, double balance, double rate) {
super(holder, balance);
this.interestRate = rate;
}
void addInterest() {
balance += balance * interestRate;
System.out.println("After interest: Rs." + balance);
}
}
class CurrentAccount extends BankAccount {
double overdraftLimit;
CurrentAccount(String holder, double balance, double limit) {
super(holder, balance);
this.overdraftLimit = limit;
}
@Override
void withdraw(double amount) {
if (amount > balance + overdraftLimit) {
System.out.println("Exceeds overdraft limit");
} else {
balance -= amount;
System.out.println("Withdrew Rs." + amount + (balance < 0 ? " (using overdraft)" : ""));
}
}
}
public class Main {
public static void main(String[] args) {
SavingsAccount sa = new SavingsAccount("Priya", 10000, 0.05);
System.out.println("Savings - " + sa);
sa.addInterest();
CurrentAccount ca = new CurrentAccount("Aarav", 5000, 10000);
System.out.println("Current - " + ca);
ca.withdraw(7000);
System.out.println("Balance: Rs." + ca.balance);
}
}Challenge 5: Vehicle Hierarchy with toString and equals
HardCreate a Vehicle class with brand and year. Override toString() and equals() (and hashCode()). Create Car (with numDoors) and Motorcycle (with hasSidecar) subclasses that extend toString() and equals(). Demonstrate equality checks.
Sample Input
(No input required)
Sample Output
Car{brand='Toyota', year=2024, doors=4}
Car{brand='Toyota', year=2024, doors=4}
Are they equal? true
Motorcycle{brand='Honda', year=2023, sidecar=false}
Car equals Motorcycle? false
Override equals() and hashCode() in both parent and child classes. Use @Override annotation.
class Vehicle {
String brand;
int year;
Vehicle(String brand, int year) {
this.brand = brand;
this.year = year;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
Vehicle v = (Vehicle) obj;
return year == v.year && brand.equals(v.brand);
}
@Override
public int hashCode() { return 31 * brand.hashCode() + year; }
@Override
public String toString() { return "Vehicle{" + brand + ", " + year + "}"; }
}
class Car extends Vehicle {
int numDoors;
Car(String brand, int year, int numDoors) {
super(brand, year);
this.numDoors = numDoors;
}
@Override
public boolean equals(Object obj) {
if (!super.equals(obj)) return false;
Car c = (Car) obj;
return numDoors == c.numDoors;
}
@Override
public int hashCode() { return 31 * super.hashCode() + numDoors; }
@Override
public String toString() {
return "Car{brand='" + brand + "', year=" + year + ", doors=" + numDoors + "}";
}
}
class Motorcycle extends Vehicle {
boolean hasSidecar;
Motorcycle(String brand, int year, boolean hasSidecar) {
super(brand, year);
this.hasSidecar = hasSidecar;
}
@Override
public String toString() {
return "Motorcycle{brand='" + brand + "', year=" + year + ", sidecar=" + hasSidecar + "}";
}
}
public class Main {
public static void main(String[] args) {
Car c1 = new Car("Toyota", 2024, 4);
Car c2 = new Car("Toyota", 2024, 4);
System.out.println(c1);
System.out.println(c2);
System.out.println("Are they equal? " + c1.equals(c2));
Motorcycle m = new Motorcycle("Honda", 2023, false);
System.out.println(m);
System.out.println("Car equals Motorcycle? " + c1.equals(m));
}
}Challenge 6: Custom Exception Hierarchy
HardCreate a custom exception hierarchy: AppException extends Exception, ValidationException extends AppException, and NotFoundException extends AppException. Each should have a constructor that takes a message. Write a method that throws different exceptions based on input and catch them appropriately.
Sample Input
(No input required)
Sample Output
ValidationException: Age must be positive: -5
NotFoundException: Student not found: ID 999
AppException: General application error
Use inheritance for the exception hierarchy. Demonstrate catching specific and general exceptions.
class AppException extends Exception {
AppException(String msg) { super(msg); }
}
class ValidationException extends AppException {
ValidationException(String msg) { super(msg); }
}
class NotFoundException extends AppException {
NotFoundException(String msg) { super(msg); }
}
public class Main {
static void process(int code) throws AppException {
if (code == 1) throw new ValidationException("Age must be positive: -5");
if (code == 2) throw new NotFoundException("Student not found: ID 999");
if (code == 3) throw new AppException("General application error");
}
public static void main(String[] args) {
for (int i = 1; i <= 3; i++) {
try {
process(i);
} catch (ValidationException e) {
System.out.println("ValidationException: " + e.getMessage());
} catch (NotFoundException e) {
System.out.println("NotFoundException: " + e.getMessage());
} catch (AppException e) {
System.out.println("AppException: " + e.getMessage());
}
}
}
}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