Quick answer
OOP in Python organises code around objects that bundle data (attributes) with behaviour (methods). Interviewers expect you to explain four pillars: encapsulation (hiding internal state), inheritance (reusing a parent class), polymorphism (one interface, many implementations), and abstraction (exposing only what matters).
OOP (Object-Oriented Programming) in Python organises code around objects that bundle data (attributes) with behaviour (methods). Interviewers expect you to name the four pillars — encapsulation, inheritance, polymorphism, and abstraction — and show each in code. Here are the questions that come up most, with answers you can say out loud.
1. What is the difference between a class and an object?
A class is a blueprint; an object is a concrete instance of it.
class Dog: # the blueprint
def __init__(self, name):
self.name = name
d = Dog("Rex") # d is an object (instance) of DogOne class, many objects — each with its own data.
2. What are the four pillars of OOP?
- Encapsulation — bundling data with the methods that operate on it, and controlling access.
- Inheritance — a class deriving attributes and behaviour from another.
- Polymorphism — the same call behaving differently depending on the object.
- Abstraction — exposing a simple interface and hiding the implementation.
3. How does inheritance work in Python?
A subclass names its parent in parentheses and can extend or override it, calling
the parent version with super():
class Animal:
def speak(self): return "..."
class Dog(Animal):
def speak(self): return "Woof" # overrides Animal.speakPython supports multiple inheritance and resolves method lookup through the
MRO (method resolution order), which you can inspect with
Dog.__mro__. See how inheritance works in Python
for the full mechanics.
4. Can you give an example of polymorphism?
Polymorphism in Python is duck-typed — it depends on the method existing, not on a shared base class:
class Cat:
def speak(self): return "Meow"
for animal in [Dog(), Cat()]:
print(animal.speak()) # Woof / Meow — same call, different behaviourMore detail in understanding polymorphism in Python.
5. How do you implement encapsulation?
Python has no truly private members — it uses convention:
class Account:
def __init__(self):
self._balance = 0 # single underscore: "internal, please don't touch"
self.__pin = 1234 # double underscore: name-mangled to _Account__pinA single leading underscore signals internal use; a double underscore triggers
name mangling, which discourages (but does not prevent) access. Expose
controlled access with @property:
class Account:
def __init__(self): self._balance = 0
@property
def balance(self): # read-only from outside
return self._balance6. What is abstraction, and how do you enforce it?
Use abc.ABC and @abstractmethod to define an interface subclasses must
implement:
from abc import ABC, abstractmethod
class Shape(ABC):
@abstractmethod
def area(self): ...
class Circle(Shape):
def __init__(self, r): self.r = r
def area(self): return 3.14159 * self.r ** 2Instantiating Shape() directly raises TypeError — you must subclass and
implement area.
7. What are dunder methods, and why do they matter?
Double-underscore methods like __init__, __str__, and __eq__ let your
classes integrate with Python's operators and built-ins. Knowing them signals
you understand the data model, not just class syntax:
class Money:
def __init__(self, cents): self.cents = cents
def __eq__(self, other): return self.cents == other.cents
def __repr__(self): return f"Money({self.cents})"8. What's the difference between a class method, static method, and instance method?
class C:
def instance_method(self): ... # receives the instance (self)
@classmethod
def class_method(cls): ... # receives the class (cls)
@staticmethod
def static_method(): ... # receives nothing specialUse @classmethod for alternative constructors, @staticmethod for utility
functions that logically belong to the class.
Related reading
Key takeaways
- •The four pillars are encapsulation, inheritance, polymorphism, and abstraction — name them explicitly before explaining any one of them.
- •A class is a blueprint; an object is an instance of that blueprint allocated in memory.
- •Python has no true private members — a leading underscore is convention, and double underscore only triggers name mangling.
- •Python supports multiple inheritance and resolves conflicts via the MRO (method resolution order), which you can inspect with ClassName.__mro__.
- •Polymorphism in Python is duck-typed: it depends on the method existing, not on a shared base class.
Frequently asked questions
What is the difference between a class and an object in Python?
A class is the blueprint that defines attributes and methods; an object is a concrete instance of that class holding its own data. Defining `class Dog:` creates the blueprint, while `dog = Dog()` creates an object in memory.
Does Python support multiple inheritance?
Yes. A Python class can inherit from several parents, and Python resolves ambiguity using the C3 linearisation algorithm, exposed as the method resolution order (MRO). Inspect it with `ClassName.__mro__` or `ClassName.mro()`.
Are there truly private attributes in Python?
No. Python relies on convention: a single leading underscore signals internal use, and a double leading underscore triggers name mangling (`__x` becomes `_ClassName__x`), which discourages access but does not prevent it.
What is the difference between polymorphism and inheritance?
Inheritance is a reuse mechanism where a child class derives from a parent. Polymorphism is the ability to call the same method on different types and get type-appropriate behaviour. Python achieves polymorphism through duck typing, so inheritance is not required.
What are dunder methods and why do interviewers ask about them?
Dunder (double underscore) methods such as `__init__`, `__str__`, and `__eq__` let your classes integrate with Python's built-in operators and functions. They demonstrate understanding of the data model rather than just class syntax.