The interviewer asks you to name the four pillars of OOP. You list them in one breath: encapsulation, abstraction, inheritance, polymorphism. They ask, "So what is the difference between encapsulation and abstraction?" You start a sentence about hiding things, realise both answers are about hiding things, and stop.
That is how most OOPs interview questions work. The names are the warm-up. The real question is whether you know why each idea exists and what goes wrong without it.
The short answer
OOPs interview questions for freshers come from a small pool: classes and objects, the four pillars, inheritance and the diamond problem, polymorphism and dynamic dispatch, constructors and copying, class relationships, coupling and cohesion, the SOLID principles, a handful of design patterns and one small design exercise. Below are 25 object oriented programming interview questions with model answers that explain the why, examples in Java, Python or C++, and the follow-up you are most likely to hear. Learn the reasoning, then say each answer out loud.
This article is language-agnostic. For Java specifics such as equals and hashCode, Strings and collections, see our Java interview questions for freshers. For the wider plan, see the interview preparation guide for freshers.
Classes and the four pillars
1. What is the difference between a class and an object?
A class is a blueprint: it declares what data an object holds and what it can do. An object is one instance built from that blueprint, with its own values in memory. Car is a class; the red car with registration KA01 is an object.
2. What are the four pillars of OOP, and why does each exist?
- Encapsulation keeps data and the methods that change it together, behind a controlled interface. Why: if any code can set
balance = -500, no rule about balances can be enforced. - Abstraction exposes what something does and hides how. Why: callers depend on a small, stable surface, so the implementation can change without breaking them.
- Inheritance lets a class reuse and extend another class. Why: shared behaviour is written once.
- Polymorphism lets one call behave correctly for different types. Why: code written against
Shapeworks for every shape, including ones added next year.
3. Encapsulation vs abstraction: what is the difference?
Abstraction is a design decision about what to show: an interface PaymentGateway with a charge() method. Encapsulation is the mechanism that protects an object's state: private fields that only the class's own methods can change. Abstraction answers "what does the caller need to know?"; encapsulation answers "who is allowed to touch this data?"
Inheritance and polymorphism
4. What are the types of inheritance?
Single (one parent), multilevel (A to B to C), hierarchical (several children of one parent), multiple (one child, several parents) and hybrid (a mix). C++ and Python support multiple inheritance of classes. Java allows only single inheritance of classes, but a class can implement many interfaces.
Likely follow-up: "Why did Java leave out multiple class inheritance?" To avoid the ambiguity in the next question.
5. What is the diamond problem, and how do C++, Java and Python handle it?
B and C both inherit from A, and D inherits from both B and C. If B and C each override a method from A, which one does D get, and does D contain one copy of A's data or two?
- C++ gives D two copies of A by default, and an ambiguous call is a compile error. Declaring
class B : virtual public A(and the same for C) makes them share one A, and D must override if B and C disagree. - Java sidesteps it for state, since a class has only one superclass. With interfaces, if two
defaultmethods clash, the compiler forces the class to override and pick one, for example withB.super.hello(). - Python uses the method resolution order, computed by C3 linearisation. You can see it with
D.__mro__(D, B, C, A, object), andsuper()follows that order, so A's method runs once.
6. Compile-time vs runtime polymorphism?
Compile-time polymorphism is resolved by the compiler from the static types: method overloading, operator overloading in C++, and templates. Runtime polymorphism is resolved while the program runs, from the object's actual type: method overriding. Runtime is what lets you add a subclass without editing its callers.
7. What is a virtual function, and how does dynamic dispatch work?
A virtual function is one whose call is decided by the object's real type, not the type of the pointer or reference. In C++ you must mark it virtual; without it, Shape* s = new Circle(); s->area(); calls Shape::area. Compilers usually implement this with a vtable: a per-class table of function pointers that each object points to. In Java, non-static, non-private, non-final methods are virtual by default; in Python, every method lookup is dynamic.
Likely follow-up: "Why should a base class have a virtual destructor?" Deleting a derived object through a base pointer without one is undefined behaviour, and in practice the derived destructor never runs.
8. Method overloading vs overriding?
Overloading is several methods with one name and different parameters, chosen at compile time. Overriding is a subclass replacing a parent method with the same signature, chosen at runtime. Python has no overloading by signature: a second def with the same name replaces the first, so you use default arguments or functools.singledispatch instead.
9. Abstract class vs interface, conceptually?
An abstract class is a partial implementation: it can hold state, constructors and shared code, and it says "is a kind of". An interface is a contract: it says "can do", and unrelated classes can share it. Use an abstract class when related types share real code and data; use an interface when you only need a common capability. C++ uses a class of pure virtual functions; Python uses abc.ABC.
Object lifecycle and members
10. What do constructors and destructors do?
A constructor puts a new object into a valid state, so no code ever sees a half-built one. A destructor releases what the object holds. In C++ the destructor runs at a predictable moment, when the object goes out of scope, which is the basis of RAII: a file or lock is tied to an object's lifetime and freed automatically. Java has no destructors, and Python's __del__ has no guaranteed timing, so both use explicit scopes instead: try-with-resources and with.
Likely follow-up: "Can a constructor be private?" Yes. It stops outside code creating instances, which is how Singletons and factory methods control creation.
11. What is a copy constructor, and what is shallow vs deep copy?
A copy constructor builds a new object from an existing one, as in C++'s Buffer(const Buffer& other). The default copies each member as-is. A shallow copy copies references, so both objects point at the same inner data; a deep copy duplicates that data too. Why it matters: if a C++ class owns a raw pointer and you keep the default copy, two objects delete the same memory. That is why the rule of three says a class needing a custom destructor usually needs a custom copy constructor and copy assignment too. Python gives you copy.copy and copy.deepcopy.
12. Static vs instance members?
An instance member belongs to each object; a static (class) member is shared by all objects of the class. A static method has no this or self, so it cannot touch instance data.
Likely follow-up: "What is the trap in Python?" A mutable class attribute, like items = [] declared in the class body, is shared by every instance, so appending through one object changes them all.
13. Explain access modifiers.
private is visible only inside the class, protected adds subclasses, public is visible everywhere; Java adds package-private as the default. In C++, members of a class are private by default and members of a struct are public. Python enforces nothing: _name is a convention for "internal", and __name triggers name mangling to _ClassName__name, which avoids clashes in subclasses but is not real privacy. Default to the narrowest access, because everything public is a promise.
Relationships between classes
14. Association, aggregation and composition: what is the difference?
All three are "has a" relationships, with increasing ownership. Association means two objects know each other, such as a Teacher and a Student, and neither owns the other. Aggregation is a whole and parts that can exist on their own: a Team has Players, and the players survive if the team is dissolved. Composition is ownership: a House has Rooms, and the rooms are created and destroyed with the house.
15. Composition vs inheritance: why "favour composition"?
Inheritance is "is a" and is fixed when you write the class; composition is "has a" and holds another object you can swap. Inheritance couples the child to the parent's internals, so a change in the parent can break every child, and deep hierarchies explode with combinations: FlyingSwimmingDuck. Composition lets you assemble behaviour, such as a Duck holding a FlyBehaviour, and change it at runtime. Inheritance is still right when the "is a" is true everywhere the parent is used, which is the test in question 19.
16. What are coupling and cohesion?
Coupling is how much one class depends on another's details; cohesion is how closely a class's own responsibilities belong together. You want low coupling and high cohesion. Why: with low coupling a change stays in one place, and with high cohesion each class has one clear reason to exist and is easy to test.
SOLID
17. What is the Single Responsibility Principle?
A class should have one reason to change. Violation: a Report class that calculates totals, renders a PDF and emails it. A new PDF layout and a new tax rule both edit the same class. Fix: split it into a calculator, a renderer and a sender.
18. What is the Open/Closed Principle?
Classes should be open for extension and closed for modification. Violation: a calculateArea() with if shape == "circle" ... elif shape == "square", edited for every new shape. Fix: each shape implements area(), and a new shape is a new class.
19. What is the Liskov Substitution Principle?
A subclass must be usable anywhere its parent is expected, without surprising the caller. Classic violation: Square extends Rectangle. A caller sets width to 5 and height to 4 and expects an area of 20, but the square's setHeight also changes the width, so it gets 16.
20. What is the Interface Segregation Principle?
Clients should not depend on methods they do not use. Violation: a Worker interface with work() and eat(), which forces a Robot to implement eat() by throwing an exception. Fix: smaller interfaces such as Workable and Eatable, so each class takes only what fits.
21. What is the Dependency Inversion Principle?
High-level code should depend on abstractions, not concrete classes. Violation: OrderService does new MySqlRepository() inside itself, so you cannot test it without a database or move to another store without editing it. Fix: it takes an OrderRepository interface in its constructor, and you pass in the real one or a fake. That is dependency injection.
Design patterns and a mini design
22. What is a Singleton, and what are its pitfalls?
A class with one instance and a global access point: a private constructor plus a static getInstance(). Pitfalls are what interviewers actually want. It is global state in disguise, so dependencies are hidden and tests leak into each other. Lazy creation is not thread-safe unless you make it so: in Java use an enum or double-checked locking with a volatile field; in C++11 a function-local static is initialised thread-safely.
Likely follow-up: "What would you use instead?" Create one instance at startup and inject it where needed.
23. What is the Factory pattern?
A factory puts object creation in one place, so callers ask for an interface and do not name concrete classes: NotificationFactory.create("sms") returns a Notifier. Why: a new channel changes only the factory.
24. What are Observer and Strategy, and how are they different?
Observer: a subject keeps a list of observers and notifies them when its state changes, like a StockPrice updating several displays. It decouples the thing that changes from the things that react. Unsubscribe observers, or they leak memory. Strategy: a family of interchangeable algorithms behind one interface, such as PricingStrategy with regular and festive-sale versions, chosen at runtime instead of a growing if chain. Observer is about who gets told; Strategy is about which algorithm runs.
25. Design the classes for a parking lot.
Start with questions, not classes: how many floors, which vehicle sizes, how is payment taken? Then name the nouns: ParkingLot has Floors, a Floor has ParkingSpots, a Vehicle (with Car, Bike, Truck) occupies a spot, and a Ticket records entry time. Put fee calculation behind a PricingStrategy, and spot allocation behind an interface so "nearest to the exit" can be swapped later. Walk through one flow, entry to exit, rather than drawing every class.
Likely follow-up: "What happens if two cars try to take the last spot at once?" Allocation needs to be atomic, with a lock or a database constraint. For the full method, see our guide to the low-level design interview.
How to practise these
Practise in pairs: one person asks, then keeps asking why. When you hit something you genuinely do not know, there is a better move than guessing; see how to handle a question you don't know. If Python is your main language, the Python interview questions for freshers follow the same format.
To rehearse under real follow-ups, you can pick your track and stack for a scored round on our backend interview practice page. Sia, the AI interviewer, asks one question at a time and follows up on what you actually said, at Beginner, Standard or Senior difficulty and a round length you choose, and you get a scored written breakdown when you finish. When you want a person instead, a live 40-minute Zoom interview with a working engineer scores you on technical depth, problem solving, communication, behaviour and code quality, and ends with a numbered certificate.