25 OOP in Java questions with answers for java roles — 7 easy, 15 medium, 3 hard.
About OOP in Java
Object oriented programming is the heart of Java interviews. This topic covers classes and objects, encapsulation, inheritance, polymorphism and abstraction, interfaces versus abstract classes, equals and hashCode, immutability, records, sealed classes, SOLID principles and common design patterns like singleton, builder, factory and strategy used in real projects.
Sheet progressStart practicing
3 QUESTIONS FREESign up to unlock the full question bank and track your progress.Unlock every question and answer, then continue practising company-wise and package-wise.
✓ 3 questions free • Unlock the rest in seconds
01
What are the four pillars of OOP? Explain with Java examples.
Encapsulation hides data behind methods, for example private fields with getters and setters in a BankAccount class. Abstraction exposes only what is needed through abstract classes or interfaces, like a Payment interface. Inheritance lets a class reuse another, such as SavingsAccount extends Account. Polymorphism lets one reference behave differently, like a Payment variable calling pay() on a UpiPayment or CardPayment.
02
What is the difference between method overloading and method overriding?
Overloading means several methods in the same class share a name but differ in parameter list; it is resolved at compile time. Overriding means a subclass provides its own version of a parent method with the same signature; it is resolved at runtime through dynamic dispatch. Return type alone cannot overload a method, while overriding allows a covariant return type.
03
Why does Java not support multiple inheritance of classes?
Multiple inheritance of classes creates the diamond problem: if two parents have the same method with different code, the child cannot know which one to use, and state duplication becomes messy. Java avoids this by allowing one superclass but many interfaces. If two interfaces provide the same default method, the class must override it and can call a specific one with InterfaceName.super.method().
Constructor chaining is calling one constructor from another. this(...) calls another constructor in the same class and super(...) calls a parent class constructor; either must be the first statement. If you write neither, the compiler inserts super() automatically. Chaining avoids duplicate initialisation code, for example a no-arg constructor calling this("default", 0).
05
Can you override a static or private method in Java?
No. Private methods are not visible to subclasses, so a method with the same name in a child is a new method. Static methods belong to the class; a static method with the same signature in a child hides the parent one, and which one runs depends on the reference type, not the object. The @Override annotation on such methods gives a compile error.
06
Show runtime polymorphism with a simple Java example.
A parent reference calls the child's overridden method at runtime.
abstract class Shape {
abstract double area();
}
class Circle extends Shape {
double r = 2;
double area() { return Math.PI * r * r; }
}
class Square extends Shape {
double s = 3;
double area() { return s * s; }
}
Shape sh = new Circle();
System.out.println(sh.area()); // Circle area
07
How do you explain OOP concepts to a junior developer who is new to Java?
Situation: I mentored two interns who struggled with OOP. Task: help them design classes for a library app. Action: I used real objects they knew, like Book and Member, showed encapsulation with private fields, then wrote one interface with two implementations to show polymorphism, and reviewed their code daily. Result: within two weeks they designed modules on their own and their pull requests needed fewer review comments.
08
What is the difference between an abstract class and an interface in modern Java?
An abstract class can have state (instance fields), constructors and any access modifier, and a class can extend only one. An interface has no instance state but, since Java 8, can have default and static methods, and since Java 9 private methods; a class can implement many. Use an interface for a capability contract and an abstract class to share code and state among closely related classes.
09
What is the contract between equals() and hashCode()?
If two objects are equal by equals(), they must return the same hashCode(). Unequal objects may share a hash code, but fewer collisions give better performance. If you override equals() but not hashCode(), HashMap and HashSet break: an equal key lands in a different bucket and cannot be found. Use the same fields in both methods, or use records, which generate both.
Declare the class final, make all fields private and final, set them only in the constructor, and provide no setters. For mutable fields like a List or Date, make defensive copies in the constructor and in getters, or use List.copyOf. Immutable objects are thread safe and make good map keys. Java records give a concise way to create shallowly immutable data classes.
11
What is the difference between composition and inheritance, and which should you prefer?
Inheritance is an is-a relation where the subclass reuses parent code, but it creates tight coupling and fragile hierarchies. Composition is a has-a relation where a class holds another object and delegates work, such as a Car having an Engine. Prefer composition because it is flexible, allows changing behaviour at runtime and is easier to test. Use inheritance only for a true is-a relationship.
Single Responsibility: a class has one reason to change. Open/Closed: open for extension, closed for modification. Liskov Substitution: subclasses must work wherever the parent is expected. Interface Segregation: prefer small, focused interfaces. Dependency Inversion: depend on abstractions, not concrete classes. Spring dependency injection is a practical example of dependency inversion.
13
What are records in Java and when should you use them?
Records, final in Java 16, are concise classes for immutable data. record Point(int x, int y) {} generates private final fields, a canonical constructor, accessors, equals(), hashCode() and toString(). You can add validation in a compact constructor and add methods. Use them for DTOs, API responses and map keys. They cannot extend another class and are not suited to JPA entities, which need mutability.
14
What is the difference between static and dynamic binding?
Static binding is resolved at compile time and applies to private, static and final methods and to overloaded methods, because the compiler knows exactly which method to call. Dynamic binding is resolved at runtime based on the actual object type and applies to overridden instance methods. Static methods are hidden, not overridden, so the reference type decides which one runs.
15
You need to add a new payment method to a system that has a big if-else on payment type. How would you redesign it?
This breaks the Open/Closed principle. I would create a PaymentProcessor interface with a pay() method and one implementation per type, such as UpiProcessor and CardProcessor. A factory or a Spring map of beans keyed by type picks the right one. Adding a new method then means adding one new class without touching existing tested code, and each processor can be unit tested alone.
16
Objects used as HashMap keys cannot be found after insertion. What could be wrong?
Most likely the class overrides equals() but not hashCode(), or neither, so equal keys land in different buckets. Another cause is a mutable key: a field used in hashCode() was changed after insertion, so the lookup goes to a different bucket. The fix is to implement both methods on the same fields and use immutable keys such as String, records or final classes.
17
A getter returns an internal List and callers modify it, causing bugs. How do you fix this?
This breaks encapsulation. Return an unmodifiable view with Collections.unmodifiableList(list) or a copy with List.copyOf(list), so callers cannot change internal state. Also copy the list passed into the constructor or setter. If the class should be fully immutable, store List.copyOf in a final field. Expose specific methods like addItem() when controlled changes are needed.
The simplest safe options are an enum or the holder idiom.
public class Config {
private Config() {}
private static class Holder {
static final Config INSTANCE = new Config();
}
public static Config getInstance() {
return Holder.INSTANCE;
}
}
The JVM loads Holder lazily and class initialisation is thread safe. An enum singleton also resists reflection and serialization attacks.
19
Implement equals() and hashCode() for an Employee class with id and email.
Use the same fields in both methods.
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Employee e)) return false;
return id == e.id && Objects.equals(email, e.email);
}
@Override
public int hashCode() {
return Objects.hash(id, email);
}
Pattern matching for instanceof (Java 16) avoids an explicit cast.
20
Implement the Builder pattern for a User class with many optional fields.
A builder avoids long constructors.
public class User {
private final String name; private final int age;
private User(Builder b) { name = b.name; age = b.age; }
public static class Builder {
private String name; private int age;
public Builder name(String n) { name = n; return this; }
public Builder age(int a) { age = a; return this; }
public User build() { return new User(this); }
}
}
Usage: new User.Builder().name("Asha").age(25).build(). Lombok @Builder generates this.
21
Write a record with validation in its compact constructor.
A compact constructor runs before fields are assigned.
public record Money(String currency, long paise) {
public Money {
Objects.requireNonNull(currency);
if (paise < 0) {
throw new IllegalArgumentException("negative amount");
}
}
public Money add(Money o) {
return new Money(currency, paise + o.paise);
}
}
Storing money in paise as long avoids floating point errors.
22
Describe a time you improved the design of existing code.
Situation: our notification module used a 400 line class with switch cases for email, SMS and WhatsApp. Task: add push notifications without breaking anything. Action: I wrote tests for current behaviour, extracted a Notifier interface with one class per channel and used Spring to inject them by type. Result: push was added in one new class, bugs in that module dropped and new channels now take hours, not days.
Sealed classes and interfaces, final in Java 17, restrict which classes can extend them using the permits clause, for example sealed interface Shape permits Circle, Square. Each subclass must be final, sealed or non-sealed. This models a closed set of types, and with pattern matching for switch in Java 21 the compiler can check that every case is handled without a default branch.
24
What is the Liskov Substitution Principle? Give an example of breaking it.
LSP says any subclass object must be usable wherever the parent is expected without breaking behaviour. A classic violation is Square extends Rectangle: setting width also changes height, so code that sets width 5 and height 4 and expects area 20 fails. Another is a subclass throwing UnsupportedOperationException for a parent method. The fix is a better hierarchy or composition.
25
A deep inheritance hierarchy of six levels is hard to change. How would you refactor it?
I would identify which behaviours actually vary and pull them into small interfaces, then replace inheritance with composition where a class holds strategy objects. Shared helper code can move to separate components. I would refactor step by step behind existing tests, starting from the leaves, so behaviour stays the same. The result is flatter classes that are easier to test and extend.
Frequently asked questions
How important is OOP in Java in Java interviews?
Object oriented programming is the heart of Java interviews. This topic covers classes and objects, encapsulation, inheritance, polymorphism and abstraction, interfaces versus abstract classes, equals and hashCode, immutability, records, sealed classes, SOLID principles and common design patterns like singleton, builder, factory and strategy used in real projects.
How should I use the OOP in Java sheet?
Go top to bottom — easy to hard. Answer before opening each answer, tick what you solved and save misses to Last-Minute Revision.