The top 40 OOPs interview questions in Java for 2026 cluster into six groups: the 4 pillars themselves — encapsulation, abstraction, inheritance, polymorphism (35%); abstract class vs interface (15%); method overloading vs overriding (12%); constructors and initialization (10%); SOLID principles (15%); and design patterns (13%). Every Java fresher interview at TCS, Infosys, Accenture, Cognizant, and product companies includes at least 4 OOPs questions — and a code-design problem (e.g., "design a banking system") is the most common second-round task. This guide gives all 40 with answers and 12 working Java code examples.
Table of Contents
- The 4 Pillars of OOPs Compared
- Company Round Formats (TCS / Infosys / Accenture)
- Encapsulation (Q1–Q7)
- Abstraction (Q8–Q14)
- Inheritance (Q15–Q23)
- Polymorphism (Q24–Q32)
- Constructors & Initialization (Q33–Q36)
- SOLID Principles (Q37–Q40)
- 2-Week OOPs Interview Prep Plan
The 4 Pillars of OOPs Compared
| Pillar | What it does | How in Java | When to use |
|---|---|---|---|
| Encapsulation | Hides state; bundles data + methods | private fields + public getters/setters | Every class with mutable state |
| Abstraction | Hides implementation; shows only interface | abstract class, interface | When callers shouldn't depend on details |
| Inheritance | Reuses code via "is-a" hierarchy | extends (class), implements (interface) | True subtype relationship only |
| Polymorphism | One interface, many implementations | Overloading (compile-time) + Overriding (runtime) | When behavior varies by subtype |
Company Round Formats: TCS NQT, Infosys InfyTQ, Accenture
| Company Round | OOPs Format | Difficulty |
|---|---|---|
| TCS NQT (2026) | 5–7 OOP MCQs + 1 design problem (e.g., "design Employee hierarchy") | Easy to medium |
| Infosys InfyTQ (2026) | 5–6 OOP MCQs + 1 code-tracing problem (output prediction) | Easy to medium |
| Wipro NLTH (2026) | 3–4 OOP MCQs | Easy only |
| Accenture (2026) | 5–6 OOP MCQs + 1 design problem | Easy to medium |
| Cognizant GenC (2026) | 4–5 OOP MCQs | Easy to medium |
| Product companies (Flipkart, Razorpay) | 2–3 OOP design rounds + 1 system design | Medium to hard (SOLID + patterns) |
- Q1. What is encapsulation?
Answer: Bundling data (fields) and the methods that operate on that data into a single unit (a class), and restricting direct access to the data from outside. Implementation: mark fields private, expose behavior through public methods (getters/setters or domain-specific operations). Benefits: invariants can be enforced (e.g., balance cannot be negative), implementation can change without breaking callers, easier to test.
- Q2. Write an encapsulated BankAccount class in Java.
Answer: public class BankAccount {
private String owner;
private double balance; // hidden state
public BankAccount(String owner, double openingBalance) {
if (openingBalance < 0) throw new IllegalArgumentException("balance cannot be negative");
this.owner = owner;
this.balance = openingBalance;
}
public double getBalance() { return balance; } // read-only — no setter for balance
public void deposit(double amount) {
if (amount <= 0) throw new IllegalArgumentException("amount must be positive");
balance += amount;
}
public void withdraw(double amount) {
if (amount < 0) throw new IllegalArgumentException("amount must be positive");
if (amount > balance) throw new IllegalArgumentException("insufficient funds");
balance -= amount;
}
}
// balance cannot be set arbitrarily; only deposit/withdraw can change it, both with validation.
- Q3. What is the difference between
private, protected, public, and default (package-private)?
Answer: Modifier Same class Same package Subclass (other package) Other packages privateYes No No No default (package-private) Yes Yes No No protectedYes Yes Yes No publicYes Yes Yes Yes
- Q4. Why use getters and setters instead of public fields?
Answer: Public fields expose internal state; any code can read or write them, no validation, no notification of changes. Getters/setters let you: validate on set (reject negative balances), compute on get (lazy field), notify observers (event listeners), add logging/security checks, change internal representation without breaking API. JavaBeans convention requires getter/setter pairs for property access in frameworks.
- Q5. Can you make a class fully immutable?
Answer: public final class Money { // 1. final class — no subclassing
private final BigDecimal amount; // 2. final fields
private final String currency;
public Money(BigDecimal amount, String currency) { // 3. initialize in constructor
this.amount = amount;
this.currency = currency;
}
public BigDecimal getAmount() { return amount; } // 4. no setters
public String getCurrency() { return currency; }
@Override public boolean equals(Object o) { // 5. equals/hashCode for value semantics
if (!(o instanceof Money)) return false;
Money m = (Money) o;
return amount.equals(m.amount) && currency.equals(m.currency);
}
@Override public int hashCode() { return Objects.hash(amount, currency); }
}
// Immutable = final class + final fields + no setters + value-based equals/hashCode.
- Q6. What is the JavaBeans specification?
Answer: A convention for reusable Java components: private fields, public no-arg constructor, public getters/setters named getX()/setX() (or isX() for boolean). Enables frameworks like Spring and JavaServer Faces to introspect and populate objects automatically. POJO = Plain Old Java Object — same idea, less formal.
- Q7. What is a record in Java?
Answer: Java 16+ shorthand for an immutable data class. Auto-generates constructor, accessors, equals, hashCode, toString based on the components.
Abstraction (Q8–Q14)
- Q8. What is abstraction?
Answer: Hiding implementation details and showing only the essential features (the interface). Callers know what a method does, not how it does it. Implementation: abstract classes (partial implementation + abstract methods) and interfaces (pure contracts in Java 7, default methods since Java 8).
- Q9. What is an abstract class?
Answer: public abstract class Shape {
protected String color;
public Shape(String color) { this.color = color; }
public abstract double area(); // no body — subclasses MUST implement
public abstract double perimeter();
public String describe() { // concrete method — shared by all subclasses
return color + " shape with area " + area();
}
}
public class Circle extends Shape {
private double radius;
public Circle(String color, double radius) { super(color); this.radius = radius; }
@Override public double area() { return Math.PI * radius * radius; }
@Override public double perimeter() { return 2 * Math.PI * radius; }
}
// Cannot instantiate Shape directly. Subclasses must provide area() and perimeter().
- Q10. What is an interface?
Answer: public interface Drawable {
void draw(); // implicitly public abstract
default void describe() { // default method (Java 8+) — has body
System.out.println("Drawing a " + this.getClass().getSimpleName());
}
static Drawable create() { // static method (Java 8+)
return new Circle("red", 1.0); // example
}
}
public interface Loggable {
String logLevel();
private String format(String msg) { return "[" + logLevel() + "] " + msg; } // private (Java 9+)
default void log(String msg) { System.out.println(format(msg)); }
}
- Q11. When to use abstract class vs interface?
Answer: Use abstract class when Use interface when Subclasses share code (concrete methods) Classes are unrelated but share behavior Subclasses share state (instance fields) You need multiple inheritance of types You need a constructor for the base You want to specify a contract only Public API is meant to evolve in subclasses You want to add capabilities to existing classes
Rule of thumb: prefer interface for "can-do" relationships (Runnable, Comparable, Serializable); prefer abstract class for "is-a" with shared implementation.
Answer: Bundling data (fields) and the methods that operate on that data into a single unit (a class), and restricting direct access to the data from outside. Implementation: mark fields
private, expose behavior through public methods (getters/setters or domain-specific operations). Benefits: invariants can be enforced (e.g., balance cannot be negative), implementation can change without breaking callers, easier to test.Answer:
public class BankAccount {
private String owner;
private double balance; // hidden state
public BankAccount(String owner, double openingBalance) {
if (openingBalance < 0) throw new IllegalArgumentException("balance cannot be negative");
this.owner = owner;
this.balance = openingBalance;
}
public double getBalance() { return balance; } // read-only — no setter for balance
public void deposit(double amount) {
if (amount <= 0) throw new IllegalArgumentException("amount must be positive");
balance += amount;
}
public void withdraw(double amount) {
if (amount < 0) throw new IllegalArgumentException("amount must be positive");
if (amount > balance) throw new IllegalArgumentException("insufficient funds");
balance -= amount;
}
}
// balance cannot be set arbitrarily; only deposit/withdraw can change it, both with validation.private, protected, public, and default (package-private)?Answer:
| Modifier | Same class | Same package | Subclass (other package) | Other packages |
|---|---|---|---|---|
private | Yes | No | No | No |
| default (package-private) | Yes | Yes | No | No |
protected | Yes | Yes | Yes | No |
public | Yes | Yes | Yes | Yes |
Answer: Public fields expose internal state; any code can read or write them, no validation, no notification of changes. Getters/setters let you: validate on set (reject negative balances), compute on get (lazy field), notify observers (event listeners), add logging/security checks, change internal representation without breaking API. JavaBeans convention requires getter/setter pairs for property access in frameworks.
Answer:
public final class Money { // 1. final class — no subclassing
private final BigDecimal amount; // 2. final fields
private final String currency;
public Money(BigDecimal amount, String currency) { // 3. initialize in constructor
this.amount = amount;
this.currency = currency;
}
public BigDecimal getAmount() { return amount; } // 4. no setters
public String getCurrency() { return currency; }
@Override public boolean equals(Object o) { // 5. equals/hashCode for value semantics
if (!(o instanceof Money)) return false;
Money m = (Money) o;
return amount.equals(m.amount) && currency.equals(m.currency);
}
@Override public int hashCode() { return Objects.hash(amount, currency); }
}
// Immutable = final class + final fields + no setters + value-based equals/hashCode.Answer: A convention for reusable Java components: private fields, public no-arg constructor, public getters/setters named
getX()/setX() (or isX() for boolean). Enables frameworks like Spring and JavaServer Faces to introspect and populate objects automatically. POJO = Plain Old Java Object — same idea, less formal.Answer: Java 16+ shorthand for an immutable data class. Auto-generates constructor, accessors, equals, hashCode, toString based on the components.
Answer: Hiding implementation details and showing only the essential features (the interface). Callers know what a method does, not how it does it. Implementation: abstract classes (partial implementation + abstract methods) and interfaces (pure contracts in Java 7, default methods since Java 8).
Answer:
public abstract class Shape {
protected String color;
public Shape(String color) { this.color = color; }
public abstract double area(); // no body — subclasses MUST implement
public abstract double perimeter();
public String describe() { // concrete method — shared by all subclasses
return color + " shape with area " + area();
}
}
public class Circle extends Shape {
private double radius;
public Circle(String color, double radius) { super(color); this.radius = radius; }
@Override public double area() { return Math.PI * radius * radius; }
@Override public double perimeter() { return 2 * Math.PI * radius; }
}
// Cannot instantiate Shape directly. Subclasses must provide area() and perimeter().Answer:
public interface Drawable {
void draw(); // implicitly public abstract
default void describe() { // default method (Java 8+) — has body
System.out.println("Drawing a " + this.getClass().getSimpleName());
}
static Drawable create() { // static method (Java 8+)
return new Circle("red", 1.0); // example
}
}
public interface Loggable {
String logLevel();
private String format(String msg) { return "[" + logLevel() + "] " + msg; } // private (Java 9+)
default void log(String msg) { System.out.println(format(msg)); }
}Answer:
| Use abstract class when | Use interface when |
|---|---|
| Subclasses share code (concrete methods) | Classes are unrelated but share behavior |
| Subclasses share state (instance fields) | You need multiple inheritance of types |
| You need a constructor for the base | You want to specify a contract only |
| Public API is meant to evolve in subclasses | You want to add capabilities to existing classes |
Rule of thumb: prefer interface for "can-do" relationships (Runnable, Comparable, Serializable); prefer abstract class for "is-a" with shared implementation.
Answer:
public interface Readable { void read(); }
public interface Writable { void write(); }
public interface ReadWritable extends Readable, Writable { } // multiple interface inheritance
public class Document implements ReadWritable {
@Override public void read() { /* ... */ }
@Override public void write() { /* ... */ }
}
// Interfaces can extend multiple interfaces — classes can implement many interfaces.Answer: An interface with exactly one abstract method (default/static don't count). Used as the target type for lambda expressions. Annotated
@FunctionalInterface (compiler enforces). Examples: Runnable (run), Comparator (compare), Supplier<T> (get), Consumer<T> (accept), Function<T,R> (apply), Predicate<T> (test).Answer: An empty interface with no methods — just marks a class as having a capability. Examples:
Serializable (object can be serialized), Cloneable (object can be cloned), RandomAccess (list supports fast random access). Largely replaced by annotations (Java 5+), but the pattern persists in core APIs.Inheritance (Q15–Q23)
- Q15. What is inheritance?
Answer: A subclass extends a parent class, inheriting its fields and methods and overriding or extending behavior. Models an "is-a" relationship. Java uses single inheritance for classes (one parent) but supports multiple inheritance of types via interfaces. - Q16. Write an inheritance example with method overriding.
Answer:class Animal { String name; Animal(String name) { this.name = name; } String speak() { return "..."; } } class Dog extends Animal { Dog(String name) { super(name); } // call parent constructor @Override String speak() { return "Woof!"; } // override parent's method } class Cat extends Animal { Cat(String name) { super(name); } @Override String speak() { return "Meow!"; } } Animal a1 = new Dog("Rex"); Animal a2 = new Cat("Whiskers"); System.out.println(a1.speak()); // "Woof!" — dynamic dispatch picks Dog.speak() System.out.println(a2.speak()); // "Meow!" - Q17. Can a class extend multiple classes in Java?
Answer: No. Java disallows multiple class inheritance to avoid the diamond problem (ambiguity when two parents define the same method). A class can extend exactly one parent. It can implement any number of interfaces. Default methods in interfaces (Java 8+) reintroduce a form of the diamond problem for classes implementing multiple interfaces — if two interfaces define the same default method, the class must override it. - Q18. What is the diamond problem?
Answer: Ambiguity when a class inherits from two parents that both define the same method. Example:D extends B, Cwhere bothBandCdefinem()— whichm()doesDinherit? Java avoids it for classes by forbidding multiple class inheritance. For interfaces (Java 8+ default methods), the compiler enforces: the class must explicitly overridem()to disambiguate. - Q19. What is the
superkeyword?
Answer: Three uses: (1)super()calls the parent constructor — must be the first line of a subclass constructor; auto-inserted if omitted (no-arg super). (2)super.method()calls an overridden parent method from the subclass. (3)super.fieldaccesses a hidden parent field. Example:@Override String speak() { return super.speak() + " (woof)"; } - Q20. What is the difference between
this()andsuper()?
Answer:this()calls another constructor in the SAME class (constructor chaining).super()calls the parent constructor. Both must be the first line of a constructor; you can't use both in the same constructor. - Q21. What is method hiding?
Answer: When a subclass defines astaticmethod with the same signature as a parent's static method. The subclass version hides the parent's — but unlike overriding, the choice is made at compile time based on the reference type, not the runtime object.Parent.staticMethod()andChild.staticMethod()invoke different methods even if called via aParentreference to aChildobject. - Q22. What is the
finalkeyword used for in inheritance?
Answer: Three uses: (1)final classcannot be subclassed (String,Math). (2)final methodcannot be overridden by subclasses (used to lock down behavior). (3)final fieldis a constant — must be initialized in declaration or constructor and cannot be reassigned. - Q23. What is composition vs inheritance?
Answer: Inheritance: "is-a" (aSavingsAccountis aAccount). Composition: "has-a" (aCarhas anEngine). Prefer composition unless there's a clear subtype relationship — composition keeps class hierarchies shallow and avoids fragile-base-class problems.
Polymorphism (Q24–Q32)
- Q24. What is polymorphism?
Answer: One interface, many implementations. Two kinds: compile-time (static) — method overloading (same name, different parameters, resolved at compile). Runtime (dynamic) — method overriding (subclass provides different implementation, resolved at runtime via dynamic dispatch based on actual object type). - Q25. What is method overloading?
Answer:class Printer { void print(String s) { System.out.println(s); } void print(String s, int n) { for (int i = 0; i < n; i++) print(s); } // different arity void print(int n) { System.out.println("Number: " + n); } // different type void print(double d) { System.out.println("Decimal: " + d); } // different type } // Resolved at compile time based on argument types — that's why it's "compile-time polymorphism". - Q26. What is method overriding?
Answer:class Animal { String speak() { return "..."; } } class Dog extends Animal { @Override String speak() { return "Woof!"; } } Animal a = new Dog(); // reference type Animal, object type Dog System.out.println(a.speak()); // "Woof!" — runtime picks Dog.speak() (dynamic dispatch) // Rules: same name + parameters, covariant return type allowed, // access modifier not more restrictive, no new checked exceptions. - Q27. What is covariant return type?
Answer: When overriding a method, the return type can be a subtype of the parent's return type. Example: parent method returnsAnimal, child override can returnDog(a subtype). Added in Java 5. - Q28. What is the difference between overloading and overriding?
Answer:Aspect Overloading Overriding Where Same class (or subclass) Subclass only Signature Must differ (params or types) Must be identical Return type Can differ Same or covariant Binding Compile time Runtime Access modifier Can differ freely Cannot be more restrictive Exceptions Can declare new ones Cannot declare new checked exceptions - Q29. Can you override a private method?
Answer: No. Private methods are not inherited by subclasses, so there's nothing to override. You can declare a method with the same name in the subclass, but it's a brand-new method — not an override (no@Overrideshould be used). Static methods can be hidden (compile-time), but private methods can't even be hidden — they're invisible to the subclass. - Q30. What is dynamic method dispatch?
Answer: The mechanism by which the JVM decides which overridden method to invoke at runtime. The JVM looks at the actual object type (not the reference type) and dispatches to the most-specific implementation. Enables polymorphism — the same call (a.speak()) produces different behavior depending on whataactually points to. Implemented via the vtable (virtual method table) in the JVM. - Q31. What is the difference between static and dynamic binding?
Answer: Static binding (compile time): the compiler resolves the call based on the reference type. Used forstatic,private,finalmethods and overloaded methods. Dynamic binding (runtime): the JVM resolves the call based on the actual object type. Used for overridden instance methods. Static binding is faster; dynamic binding enables polymorphism. - Q32. What is the Liskov Substitution Principle?
Answer: One of SOLID. Subtypes must be substitutable for their base types without breaking the program's correctness. Practical implications: a subclass must honor all the behavioral contracts of the parent — preconditions cannot be stronger, postconditions cannot be weaker, invariants must be preserved. Example violation: aSquare extends RectanglewheresetWidthalso changes the height — violates theRectanglecontract that width and height are independent.
Constructors & Initialization (Q33–Q36)
- Q33. What is a constructor?
Answer: Special method invoked when an object is created vianew. Same name as the class, no return type. If you don't declare any constructor, the compiler generates a no-arg constructor. If you declare any constructor, the default is no longer auto-generated. - Q34. Can constructors be overloaded?
Answer:class Point { int x, y; Point() { this(0, 0); } // calls Point(int, int) Point(int x) { this(x, 0); } // calls Point(int, int) Point(int x, int y) { this.x = x; this.y = y; } // canonical Point(Point other) { this(other.x, other.y); } // copy constructor } // Constructor chaining via this() — must be the first statement. - Q35. What is constructor chaining?
Answer: Calling one constructor from another usingthis(...)(same class) orsuper(...)(parent class). Must be the first statement in the constructor body. Ensures all initialization logic runs in the correct order (parent → child). Without explicitsuper(), the compiler insertssuper()(no-arg parent constructor) — which fails if the parent has no no-arg constructor. - Q36. What is the order of initialization in Java?
Answer:- Static fields and static initializer blocks of the parent class, in declaration order
- Static fields and static initializer blocks of the child class, in declaration order
- Instance fields and instance initializer blocks of the parent, in declaration order
- Parent constructor
- Instance fields and instance initializer blocks of the child, in declaration order
- Child constructor
Memory: statics live in the method area (one per class); instance fields live in the heap (one per object).
SOLID Principles (Q37–Q40)
- Q37. What is SOLID?
Answer: Five OOP design principles coined by Robert C. Martin (Uncle Bob) for writing maintainable, extensible code. Foundation of clean architecture and Spring framework conventions. - Q38. Single Responsibility Principle (SRP)
Answer: A class should have one — and only one — reason to change. One responsibility, one axis of change. Anti-pattern: aUserServicethat handles validation, persistence, and email notifications — should be split intoUserValidator,UserRepository,EmailService. - Q39. Open/Closed Principle (OCP) + Liskov Substitution (LSP)
Answer: Open/Closed: classes should be open for extension but closed for modification — add new behavior by adding new code (subclasses, strategies) rather than editing existing code. Liskov Substitution: subtypes must be substitutable for their base types — see Q32 for the Square/Rectangle violation. - Q40. Interface Segregation (ISP) + Dependency Inversion (DIP)
Answer: Interface Segregation: prefer small, focused interfaces over fat ones. Don't force clients to depend on methods they don't use. Dependency Inversion: depend on abstractions (interfaces), not concrete classes. High-level modules should not import low-level modules directly — both should depend on abstractions.
2-Week OOPs Interview Prep Plan
| Week | Focus | Daily Target |
|---|---|---|
| Week 1 | Four pillars — write code for each, explain with a real example (banking system, employee hierarchy, payment processor) | 1 pillar deep-dive + 10 MCQs |
| Week 2 | SOLID principles with code examples + 30 common MCQs (multiple inheritance, abstract vs interface, overloading vs overriding) + 2 design problems | 1 SOLID principle + 1 design problem |
Resources and Next Steps
The authoritative sources listed above (Oracle Java Tutorials, Baeldung, Refactoring Guru, Clean Code by Robert Martin) are the canonical references for OOP fundamentals and interview preparation. For the full 25-question curated Q&A collection at all difficulty levels (Level 1 foundational, Level 2 intermediate, Level 3 advanced), see the TutorsBot Java Interview Questions hub. For related interview prep, see our Java Interview Questions, Python Interview Questions, and DBMS Interview Questions guides.






