About Us Contact Us Write for Us Advertise
Home > Java > OOP Interview Questions in Java (With Code & Traps) — Freshers to Senior
Java

OOP Interview Questions in Java (With Code & Traps) — Freshers to Senior

A senior-level Java OOP interview guide covering the four pillars with mechanics, runtime vs compile-time polymorphism, method hiding, field shadowing, exact overriding/overloading rules, interfaces vs abstract classes, the diamond problem, SOLID principles with code, and object-model traps.

Shiv Pandey
Shiv Pandey
Oct 09, 2026 | 52 views
OOP Interview Questions in Java (With Code & Traps) — Freshers to Senior

OOP questions look easy until the interviewer stops asking "what are the four pillars?" and starts asking "why does this field print the parent's value even though the object is a Child?" This is a senior-level OOP interview guide: not textbook definitions, but the mechanics interviewers actually probe — dynamic dispatch, method hiding vs overriding, the exact overriding/overloading rules, how Java dodges the diamond problem, SOLID with real code, and the field-shadowing and static-method traps that expose whether you understand the object model or just memorised it.

Interviewer's real goal: the four pillars are a warm-up. The differentiating questions are about binding (compile-time vs runtime), substitutability (Liskov), and design tradeoffs (inheritance vs composition). Answer the "why", and reach for a design principle by name.

The four pillars — with the mechanics

Q1. Explain the four pillars, and which is a compile-time vs runtime concern.

PillarWhat it buys youJava mechanism
EncapsulationHide state, expose behaviour; enforce invariantsprivate fields + getters/setters/validation
AbstractionExpose what, hide howinterface / abstract class
InheritanceReuse + IS-A specialisationextends (single) / implements (multiple)
PolymorphismOne interface, many behavioursOverriding = runtime; overloading = compile-time

Encapsulation vs abstraction (the trap): encapsulation is about bundling and protecting data; abstraction is about hiding complexity behind a simpler contract. Encapsulation is a means; abstraction is the design goal.

Polymorphism & dynamic dispatch — the heart of OOP rounds

Q2. Overriding vs overloading — and when is each resolved?

Overloading (same name, different parameter list) is resolved by the compiler using the static/declared type of the arguments — this is static (compile-time) binding. Overriding (subclass redefines a superclass method with the same signature) is resolved by the JVM at runtime using the actual object type — dynamic (runtime) binding, implemented via a per-class method table (vtable).

Q3. Predict the output — method hiding vs overriding.

class Parent {
    static String who() { return "Parent.static"; }
    String hi() { return "Parent.hi"; }
}
class Child extends Parent {
    static String who() { return "Child.static"; }   // HIDES, not overrides
    @Override String hi() { return "Child.hi"; }   // overrides
}
Parent p = new Child();
System.out.println(p.who()); // "Parent.static" — static resolved on DECLARED type
System.out.println(p.hi());  // "Child.hi"   — instance resolved on ACTUAL type

Why: static methods are not polymorphic — they are hidden, bound at compile time to the reference's type. Only instance methods are dynamically dispatched. This single example is the most common OOP trap in senior interviews.

Q4. Predict the output — field shadowing.

class A { int x = 10; }
class B extends A { int x = 20; }
A ref = new B();
System.out.println(ref.x); // 10 — fields are NOT polymorphic (bound to declared type)

Fields are resolved at compile time by the reference type; methods at runtime by the object type. Never rely on field access through a superclass reference.

Q5. What are the exact rules for a valid override?

  • Same name + same parameter list (signature). Different params = overload, not override.
  • Return type must be the same or a covariant (narrower) subtype.
  • Access modifier can only widen, never narrow (a public method can't be overridden as protected).
  • Checked exceptions can only be the same or narrower; you may drop them or throw fewer/subtypes, but not broader checked exceptions.
  • private, static, and final methods cannot be overridden (private/static are hidden; final is sealed).

Q6. How is overloading resolved when multiple candidates match?

The compiler picks the most specific applicable method in three phases: (1) exact/widening primitive match, (2) autoboxing/unboxing, (3) varargs — earlier phases win.

void f(long x)     {}  // widening
void f(Integer x)  {}  // boxing
void f(int... x)   {}  // varargs
f(5); // calls f(long) — widening beats boxing beats varargs

Abstract class vs interface (modern Java)

Q7. When would you choose one over the other?

Abstract classInterface (Java 8+)
Multiple inheritanceNo (single extends)Yes (many implements)
State (instance fields)YesNo (only static final constants)
Method bodiesConcrete + abstractdefault/static (Java 8), private (Java 9)
ConstructorYes (runs on subclass init)No

Rule of thumb: use an interface to define a capability/contract ("can be compared", "can be closed") that unrelated types share; use an abstract class when subclasses share state and partial implementation (a true IS-A hierarchy). Since Java 8 gave interfaces default methods, the gap narrowed — but only abstract classes hold mutable state.

Q8. If interfaces have default methods, is there a diamond problem? How does Java resolve it?

interface A { default String hi() { return "A"; } }
interface B { default String hi() { return "B"; } }
class C implements A, B {
    @Override public String hi() {
        return A.super.hi(); // MUST disambiguate explicitly
    }
}

Java forces the implementing class to override and pick a winner with InterfaceName.super.method() — a compile error otherwise. Java sidesteps the classic C++ diamond because interfaces carry behaviour but no state, so there's no ambiguous field to inherit twice — that's the real reason Java allows multiple inheritance of type but not of state.

SOLID — name them, and show the fix

PrincipleOne-line ruleSmell it fixes
SRPOne reason to change per classGod class doing parsing + IO + business rules
OCPOpen to extend, closed to modifyA growing if/switch on a type code
LSPSubtypes must be substitutableSquare extends Rectangle, breaks setWidth
ISPMany small interfaces > one fat oneImplementors forced to stub unused methods
DIPDepend on abstractions, not concretesnew MySqlRepo() hardcoded in a service

The Open/Closed fix in one snippet — replace a type switch with polymorphism (this is also the Strategy pattern):

// BEFORE: every new shape edits this method (violates OCP)
double area(Shape s) {
    if (s.type == CIRCLE) return Math.PI*s.r*s.r;
    else if (s.type == SQUARE) return s.side*s.side;
    ...
}
// AFTER: each shape owns its area(); adding a shape edits nothing
interface Shape { double area(); }
class Circle implements Shape { public double area(){ return Math.PI*r*r; } }

Inheritance vs composition, and the relationships

Q9. "Favour composition over inheritance" — why?

Inheritance is a compile-time, tightly-coupled IS-A bond: the subclass depends on the superclass's internals, and a superclass change can silently break subclasses (the "fragile base class" problem). Composition (HAS-A) injects behaviour via a field/interface, giving runtime flexibility, easier testing (mock the collaborator), and no exposure to a parent's implementation. Rule: use inheritance only for a genuine, stable IS-A; otherwise compose.

Q10. Association vs aggregation vs composition?

Association — any relationship ("a Teacher teaches Students"). Aggregation — a weak HAS-A where the part outlives the whole (a Department HAS Employees, but employees exist without it). Composition — a strong HAS-A where the part's lifecycle is owned by the whole (a House HAS Rooms; destroy the house, the rooms die). Composition = ownership; aggregation = reference.

Object model mechanics

Q11. Constructor chaining — what runs, in what order?

// On 'new Child()':
// 1. Child ctor's implicit/explicit super(...) runs FIRST
// 2. Parent's field initialisers + Parent ctor body
// 3. Child's field initialisers + Child ctor body
// super() or this() MUST be the first statement in a ctor.

Every constructor calls super() (implicitly if you don't) before its own body — so the base object is fully built before the subclass touches it. Calling an overridable method from a constructor is a bug: it dispatches to the subclass override before the subclass fields are initialised.

Q12. Why does Java not support multiple inheritance of classes?

To avoid the diamond ambiguity of state: if C extended both A and B which both extended Object with a field x, which x does C get? Java allows multiple inheritance of type (interfaces) because they hold no instance state, and forces explicit resolution for clashing default methods (Q8).

Q13. Upcasting, downcasting, and ClassCastException.

Animal a = new Dog();   // upcast — always safe, implicit
Dog d = (Dog) a;         // downcast — checked at RUNTIME
Cat c = (Cat) a;         // ClassCastException — a is really a Dog
if (a instanceof Dog dog) dog.bark(); // pattern matching (Java 16+) — safe

Rapid-fire

  • Can a constructor be final/static/overridden? No to all — constructors aren't inherited, so those modifiers are meaningless.
  • Can you override a static method? No — you hide it (Q3).
  • Abstract class with no abstract methods? Legal — it just can't be instantiated directly.
  • Interface with a main method? Legal since Java 8 (static methods allowed) — it runs.
  • Marker interface? An empty interface (Serializable, Cloneable) used as a runtime type tag.
  • Cohesion vs coupling? High cohesion (a class does one thing well) + low coupling (few dependencies) = maintainable design.

Go deeper by topic

Here's the shift that got me through senior OOP rounds: I stopped treating the four pillars as the answer and started treating them as the question. An interviewer who asks "what is polymorphism?" is really asking "do you know that fields and static methods aren't polymorphic, and can you tell me why?" So for every concept on this page, I forced myself to produce the one snippet that would surprise a junior — the field that prints the parent's value, the static method that ignores the object type, the diamond that won't compile. Once you can generate those from the object model instead of recalling them, no OOP follow-up can corner you. Learn the mechanics behind the pillars, not just their names, and you'll reason your way through anything they throw. You've got this.

Related

← Core Java interview questions · Collections interview questions →

Related Articles

Java Exception Handling Interview Questions (Traps & Best Practices) — Freshers to Senior
Java

Java Exception Handling Interview Questions (Traps & Best Practices) — Freshers to Senior

Java Multithreading Interview Questions (JMM, Locks & Traps) — Freshers to Senior
Java

Java Multithreading Interview Questions (JMM, Locks & Traps) — Freshers to Senior

Java Collections Interview Questions (Internals & Traps) — Freshers to Senior
Java

Java Collections Interview Questions (Internals & Traps) — Freshers to Senior

Advanced Java Streams Interview Questions (Senior-Level, With Code)
Java

Advanced Java Streams Interview Questions (Senior-Level, With Code)