OOPs Interview Questions for Freshers (2026) — Concepts, Traps and Answers
Updated August 2026
OOPs is the one topic that survives every filter. Whatever language you wrote the coding test in, whatever branch you are from, the technical round tends to open here — because it is the fastest way for an interviewer to find out whether you understand programming or have memorised syntax. Four definitions take thirty seconds to recite and most candidates can do it, so the questions that decide the round are the ones after that: why, when, and what breaks if you get it wrong.
It helps to know what the interviewer is actually listening for. OOP exists to manage change in large programs — to keep one part of the code from depending on the internals of another, so that a change stays local instead of rippling outwards. Every pillar is one tactic for that. Encapsulation hides internals behind a small surface. Abstraction decides what that surface should be. Inheritance and interfaces let unrelated code depend on a shape rather than a specific class. Polymorphism lets a new implementation slot in without the calling code being edited. An answer that connects a definition to that purpose sounds like understanding; an answer that stops at the definition sounds like a textbook, and the follow-up question comes immediately.
One practical note before the list. These questions are language-agnostic in principle, but you will be asked them in one language, and interviewers at TCS, Infosys, Cognizant, Capgemini and most mass recruiters default to Java examples even when your resume says Python. Learn the concept once, then keep one concrete example per pillar ready in the language you are strongest in, and know the two or three places your language differs from Java — Python has no private keyword and allows multiple inheritance, C++ has both multiple inheritance and destructors, JavaScript uses prototypes rather than classical classes. Naming the difference yourself is a much better look than being corrected on it.
Frequently asked questions
What is object-oriented programming, and what problem does it solve?
It is a way of organising a program around objects — units that hold data and the operations on that data together — rather than around procedures that pass data between them. The problem it addresses is change in large codebases. When data is global and functions operate on it from anywhere, a small change can break code you have never read, because nothing limits who depends on what. Grouping state with the behaviour that owns it, and exposing only a narrow public surface, keeps most changes local to one class. Say that, rather than "it models real-world entities" — the real-world framing is how OOP is taught, but it is not why professional codebases use it, and interviewers who work on real systems can tell the difference.
What are the four pillars of OOP?
Encapsulation — bundling data with the methods that operate on it and restricting direct access to the internals. Abstraction — exposing only what a caller needs to know and hiding how it is done. Inheritance — a class acquiring the properties and behaviour of another, so shared code is written once. Polymorphism — one interface with many implementations, so calling code works against the general shape and the specific type is decided at compile time or at runtime. Give each in one line as above, then stop and let the interviewer pick which one to go deeper on. Candidates who volunteer a paragraph per pillar unprompted usually run out of substance by the third one.
What is encapsulation, and why is it more than making variables private?
Encapsulation is keeping an object's state private and letting the outside world change it only through methods that the object controls. The private keyword is the mechanism; the point is the control. A class with private fields and a public getter and setter for every one of them is not encapsulated in any meaningful sense — it is a struct with extra typing, because anyone can still put it into any state they like. The useful version is a class whose methods express operations rather than field assignments: an account with deposit and withdraw, where withdraw can refuse an overdraft, instead of a setBalance that anybody may call with any number. If you can give that example, the answer lands. In Python the mechanism is convention rather than enforcement — a leading underscore signals private and a double underscore triggers name mangling — and saying so is a good sign, not a weakness.
Abstraction versus encapsulation — what is the actual difference?
This is the most common trip-up in the whole topic, because both involve hiding something. Abstraction is a design decision: what should this thing look like from outside, which operations belong on its surface, what does the caller not need to care about. Encapsulation is the implementation of that decision: keeping the internals inaccessible so the surface is the only way in. One way to phrase it in an interview is that abstraction happens when you decide a car exposes accelerate and brake rather than fuel-injection timing, and encapsulation is the bodywork that stops you reaching the engine. Another framing that interviewers like: abstraction is about the interface, encapsulation is about the boundary that protects it. Both, notice, are the same underlying goal — the caller depends on as little as possible.
What is inheritance, and when is it the wrong tool?
Inheritance lets a class take on the fields and methods of a parent, so common behaviour is written once and specialised where it differs. It gives you code reuse and, more importantly, a type relationship — a Dog is an Animal, so anything that accepts an Animal accepts a Dog. The second half of the question is the one worth preparing, because inheritance is over-used by freshers. It is the wrong tool whenever the relationship is not genuinely is-a: inheriting from a class just to reuse three of its methods drags along all its other behaviour, ties you to its internals, and locks you to one parent in languages with single inheritance. The test to state out loud is that every place the parent type is accepted, the child must be usable without surprising anyone — if that is not true, you want composition instead.
What is polymorphism, and what are its two forms?
Polymorphism means the same call does different things depending on the actual type behind it. Compile-time polymorphism is resolved when the code is compiled and is what method overloading gives you — the compiler picks an implementation from the argument types. Runtime polymorphism is resolved while the program runs and is what overriding gives you — a reference of the parent type points at a child object, and the child's version of the method executes. The runtime form is the one that matters, because it is what lets you write a loop over a list of Shape and call area() on each without knowing or caring which shapes are in it, and add a new shape later without editing that loop. Note that dynamically typed languages such as Python get the same effect through duck typing rather than through a declared parent type — anything with an area() method works, no inheritance required.
Method overloading versus method overriding?
Overloading is two or more methods in the same class with the same name and different parameter lists; the compiler chooses between them from the arguments at the call site, so it is compile-time or static binding. Overriding is a subclass replacing a method it inherited, with the same name and the same signature; the choice happens at runtime from the object's actual type, so it is dynamic binding. Two details that separate a prepared candidate. Return type alone cannot distinguish overloads, because the compiler has nothing to choose from at the call site. And an overriding method cannot be more restrictive in visibility than the one it replaces, or widen its checked exceptions — doing so would break code that calls through the parent type. Python has no overloading in the Java sense at all: a second definition simply replaces the first, and default or variable arguments do that job instead.
Abstract class versus interface — when do you use which?
An abstract class is a partially built class: it can hold state, define constructors, and mix concrete methods with abstract ones, and a class may extend only one. An interface is a contract of behaviour, holds no instance state, and a class may implement many. The choice follows from that. Use an abstract class when subclasses genuinely share both identity and implementation — a common base with real code in it. Use an interface when unrelated types need to be usable in the same way, which is most of the time in practice. Be aware that the line has blurred: Java 8 added default and static methods to interfaces, so "an interface cannot have method bodies" is now wrong, and C# and modern Java both allow it. What has not changed is that an interface still carries no instance state and still permits multiple implementation, which is the reason to prefer it as a default.
Composition versus inheritance — what is the rule of thumb?
Inheritance is an is-a relationship, composition is a has-a: a Car is a Vehicle, but a Car has an Engine. The advice you should be able to state is "favour composition over inheritance", and the reason is coupling. A subclass depends on its parent's internals, so a change in the parent can break it silently, and the relationship is fixed at compile time and cannot be swapped. A composed object depends only on the collaborator's public interface, can be replaced at runtime, and can hold several collaborators where single inheritance allows one parent. The concrete example interviewers respond to: a Stack that extends ArrayList inherits every list operation, including inserting into the middle, which destroys the guarantee a stack exists to provide — a Stack that holds an ArrayList exposes only push and pop. Note this is a preference, not a ban; inheritance is right when the type relationship is real and you want callers to treat the subtype as the parent.
What is a class and what is an object?
A class is the definition — the fields and methods a thing of that kind will have. An object is one instance of it, created at runtime with its own copy of the instance data. The one-line version is that the class is the blueprint and the object is the building, and interviewers accept it, but be ready for the follow-up about what actually exists in memory: instance fields live per object, while the method code and any static members exist once and are shared. That distinction is what the next few questions about static members are built on, so it is worth having in the same breath rather than as a separate fact.
What is a constructor? Can it be overloaded, and can it be overridden?
A constructor is the special method that runs when an object is created, to put it into a valid initial state; it has the class name and no return type, and if you write none, most languages supply a default no-argument one. Yes, it can be overloaded — several constructors with different parameter lists are normal, and one usually delegates to another rather than repeating the initialisation. No, it cannot be overridden, because overriding requires inheriting a method by name and constructors are not inherited. What a subclass does instead is call the parent constructor as its first action, explicitly or implicitly, so the parent part of the object is initialised before the child part. Also worth knowing: writing any constructor removes the free default one, which is why adding a parameterised constructor sometimes breaks code that used to compile.
What are access modifiers, and what does each one mean?
They control who can see a member. In Java: private is the class only, default or package-private is any class in the same package, protected is the package plus subclasses anywhere, and public is everyone. C++ has private, protected and public with friend as an escape hatch; Python has no enforcement at all, only the underscore conventions. The principle to state is that you start at the most restrictive level that works and widen only when there is a reason — every member you make public becomes something other code can depend on, and therefore something you cannot change freely later. A small trap that gets asked: protected in Java is wider than most freshers assume, since it includes the whole package, not only subclasses.
What is the difference between static and instance members?
An instance member belongs to an individual object and each object has its own copy; a static member belongs to the class itself and exists once, shared by every instance and reachable without creating one. The usual honest uses of static are constants, counters that genuinely count across all instances, and stateless utility methods. The follow-up interviewers ask is why a static method cannot use an instance variable directly, and the answer is simply that it runs without any particular object, so there is no instance whose field it could mean. One caution worth adding unprompted, because it shows some experience: mutable static state is shared by everything in the process, which makes it a common source of bugs in multi-threaded code and a nuisance in tests, so use it sparingly.
What does the this or self reference mean?
It refers to the current object — the instance whose method is executing. Its two everyday uses are disambiguating a field from a parameter of the same name, as in this.name = name inside a setter, and passing the current object to something else. In Java it also lets one constructor call another with this(...). Python differs in a way worth mentioning: self is not a keyword but an ordinary first parameter that the language passes for you, which is why it appears in every method definition. If the interviewer pushes further, the useful thing to know is that static methods have no this, for the same reason they cannot touch instance fields — there is no current object.
What is multiple inheritance and the diamond problem?
Multiple inheritance is a class having more than one direct parent. The diamond problem is what happens when two of those parents inherit from a common ancestor: if both override the same method, the compiler cannot tell which version the child should get, and in C++ the ancestor's state can even be duplicated. Languages resolve it differently, and naming that is the substance of the answer. Java forbids multiple class inheritance and allows multiple interfaces instead, since interfaces carried no implementation to conflict — and when default methods arrived, Java required the class to override explicitly whenever two interfaces supply the same default. C++ allows it and offers virtual inheritance to share the base. Python allows it and resolves the order deterministically with the C3 linearisation, exposed as the MRO. The point is not to memorise the algorithms; it is to say that the ambiguity is real and each language picked a rule for it.
How does runtime polymorphism actually work under the hood?
Through a lookup that happens at call time rather than at compile time. In Java and C++ the usual implementation is a virtual method table: each class with overridable methods has a table of pointers to its versions, each object knows its class, and the call goes through that table, so the object's real type selects the implementation regardless of the reference type used at the call site. In Python the mechanism is a dictionary lookup along the method resolution order. You will not be marked down for not knowing vtables, but if you can say that the object carries its type information and the method is chosen from the object rather than from the declared reference, you have said the thing the question exists to test — and it explains why a parent-typed variable holding a child object runs the child's method.
Can you override a static method, or a private one?
Neither, and the reasons are different, which is what makes it a good trap. A static method belongs to the class and is bound at compile time from the reference type — writing a static method with the same signature in a subclass is method hiding, not overriding, and which one runs depends on the type you called it through, not on the object. A private method is not visible to the subclass at all, so a same-named method there is simply a new, unrelated method; nothing is inherited to override. Java also has final, which explicitly forbids overriding, and constructors, which are not inherited. If you can name hiding as the correct term for the static case, you are ahead of most candidates, because the usual answer is a confident and wrong yes.
Why do equals and hashCode have to be overridden together?
Because hash-based collections depend on a contract between them: two objects that are equal must return the same hash code. Override only equals and you break it — two objects your code considers equal land in different buckets, so a HashSet holds both and a HashMap lookup with an equal key misses. Override only hashCode and equality still uses reference identity, so nothing dedupes. The reverse direction is allowed and worth stating: two unequal objects may share a hash code, which is an ordinary collision the collection handles. Python has the same contract as __eq__ and __hash__, with a detail worth naming — defining __eq__ sets __hash__ to None, making the class unhashable unless you define it too. This question is really a check on whether you have used collections beyond the syllabus.
What are coupling and cohesion?
Coupling is how much one module depends on the internals of another; cohesion is how closely the things inside one module belong together. You want low coupling and high cohesion, and the two are related — a class that does one job well tends to need less from its neighbours. Made concrete: a class that reads a config file, computes a payroll and emails a payslip has low cohesion, because those three change for unrelated reasons, and it is probably tightly coupled to a mail library and a file format as well. Interviewers ask this to see whether you can talk about design at all, so a short definition plus one example of each is enough. Connecting it back to encapsulation — the narrower the public surface, the less anything can couple to — is a good way to close.
What are the SOLID principles, at a fresher level?
Five design guidelines. Single responsibility — a class should have one reason to change. Open-closed — you should be able to extend behaviour without editing existing code, typically by adding a new implementation of an interface. Liskov substitution — a subtype must be usable anywhere its parent is, without the caller needing to know. Interface segregation — many small interfaces beat one large one, so implementers are not forced to supply methods they do not need. Dependency inversion — depend on abstractions rather than on concrete classes. Do not pretend to more depth than you have; naming them and explaining one or two properly is a better answer than a shaky pass over all five. Liskov is the one worth being able to explain, because it is the formal version of the earlier inheritance test and it is the one interviewers use as a follow-up.
The interviewer says "design a class for a library" — what are they looking for?
They are testing whether you can turn a vague requirement into objects, not whether you can produce a correct system in five minutes. Work out loud in a fixed order: name the entities and what each one owns — Book, Member, Loan, Catalogue — then the operations, then the relationships between them, then the rules that must not be violated, such as one copy not being on loan twice. Two habits interviewers reward: putting each rule inside the object that owns the data it protects rather than in a controller outside, and noticing where inheritance is tempting but composition is right — a Loan has a Book, and an EBook is probably a kind of item rather than a subclass of a physical book. Ask a clarifying question or two before you start, and state your assumptions. Candidates who begin drawing immediately usually design the wrong thing quickly.
Is OOP asked in the 2027-batch aptitude and online tests, or only in interviews?
Both, in different forms. The online tests at mass recruiters typically carry a technical MCQ section where OOP appears as definitions and small output-prediction snippets — which method runs, what does this print, is this legal — so the recall version does get tested. The interview is where the reasoning version is tested, and that is where the marks actually move. Prepare in that order if you are early in the 2027-batch cycle: get the definitions and the classic traps solid enough for MCQs first, since that is cheap, then spend the longer effort on being able to justify each one, because the round that decides your offer is a conversation, not a checkbox.
I wrote my coding test in Python but the interviewer asked Java OOP questions — how should I handle that?
Answer the concept in the language you know, and say which one you are using. Something like "in Python I would express it this way, and in Java it would be private fields with a public method" is an entirely acceptable answer and shows the concept is not tied to syntax for you. What loses marks is bluffing Java specifics you do not have — access modifiers, checked exceptions, interfaces — because the follow-up question exposes it in one step. Before interview season, spend a few hours on exactly the places Python differs, since those are what interviewers probe: no access modifiers or enforced privacy, no overloading, multiple inheritance allowed with a defined resolution order, and duck typing in place of declared interfaces. That is a short list and knowing it turns an awkward moment into a good one.
How much OOP is enough for the 2026-batch off-campus drives happening now?
For service companies and most fresher roles, enough is: the four pillars with a real example each, overloading versus overriding, abstract class versus interface, composition versus inheritance, and the ability to sketch three or four classes for a small problem out loud. That set covers the overwhelming majority of what gets asked, and it is a few days of honest work rather than weeks. Product companies weight data structures and problem-solving much more heavily and ask OOP mainly through design questions, so if that is your target, put the extra hours into DSA and into low-level design practice rather than into more OOP definitions. Either way, practise saying the answers aloud — the gap between candidates who know this topic and candidates who can explain it under pressure is wide, and it is the second group that gets the offer.
Don't just read OOPs concepts questions — get asked them
Phiny's AI interviews you on exactly these topics, follows up on weak answers, and tells you what a stronger answer looks like. Text interviews are free and unlimited.
Start a free AI mock interviewHow to prepare
- Learn each pillar as a purpose, not a definition. Encapsulation protects invariants, abstraction decides the surface, inheritance and interfaces let callers depend on a shape, polymorphism lets a new implementation slot in unedited. Interviewers ask "why" after every definition, and this is the answer to all four.
- Keep one concrete example per pillar ready, in the language you are strongest in — a BankAccount that refuses an overdraft for encapsulation, a Shape list for polymorphism. A definition followed by an example in one breath is the single most reliable way to sound prepared.
- Prepare the four traps deliberately, because they are asked more than anything else: overloading versus overriding, abstract class versus interface, composition versus inheritance, and whether a static or private method can be overridden. Getting the last one right, with hiding as the correct term, puts you ahead of most candidates.
- Know where your language differs from Java, and say it before you are corrected. Python has no enforced privacy and no overloading but does allow multiple inheritance; C++ allows multiple inheritance with virtual bases; JavaScript is prototype-based. Naming the difference reads as understanding, being caught out on it reads as memorisation.
- Practise a five-minute class design out loud — a library, a parking lot, a food-delivery order. Entities, then operations, then relationships, then the rules that must not break. This is how OOP is really tested once you are past the definitions.
- Do not over-claim on SOLID. Naming five principles and explaining Liskov properly beats a vague pass over all of them, and the vague version invites exactly the follow-up you cannot answer.
- Say your answers aloud before the interview, ideally to something that asks follow-ups. Most candidates lose this topic not by not knowing it but by explaining it in a tangle under pressure, and that is only fixed by rehearsal.
Where these questions get asked
- TCS NQT guide and Infosys hiring guide — the two biggest exams these questions appear in.
- All company placement guides — pattern, syllabus and rounds for every mass recruiter.