OOP Intermediate — Practice Questions
50 questions. Try each one yourself before checking the answer.
Define an Animal class with a name attribute, then a Dog class that INHERITS from it (class Dog(Animal):) with just pass. Create a Dog and print its name.
Give Animal a method speak() that prints "Some sound". Show that Dog (with no methods of its own) can still call .speak() because it's inherited.
Give Dog its OWN speak() method that prints "Woof!", overriding Animal's version.
Give Dog its own __init__ that calls Animal's __init__ using super().__init__(name), then also sets a Dog-only attribute breed.
Given my_dog = Dog("Rex", "Labrador"), print isinstance(my_dog, Dog) and isinstance(my_dog, Animal).
Print issubclass(Dog, Animal) and issubclass(Animal, Dog), explaining the asymmetry.
Define Animal with speak(), then two subclasses Dog and Cat, each overriding speak() differently. Call both.
Define a BankAccount class storing balance in self._balance (single leading underscore), with a get_balance() method to read it.
Define an Engine class with a start() method, and a Car class that HAS an Engine (composition), delegating to it.
Given Dog and Cat classes both with a speak() method, loop through a list containing one of each and call .speak() on each — the same call, different behavior.
Give Dog a speak() method that calls Animal's speak() via super().speak() FIRST, then adds its own extra line — extending rather than fully replacing the parent behavior.
Use the @property decorator to expose _balance as a read-only balance attribute (accessed WITHOUT parentheses, but still computed by a method).
Add a @balance.setter to BankAccount that raises a ValueError if you try to set a negative balance, then demonstrate both a valid and invalid assignment.
Demonstrate a DOUBLE-underscore attribute (self.__balance) and show that Python "mangles" its name (_ClassName__balance), making accidental external access harder (though not impossible).
Define a Shape base class with an area() method returning 0 by default, then Circle and Square subclasses each overriding it correctly.
Using Circle and Square (from Q15), loop through a list of mixed shapes and print each one's area(), without checking their specific type.
Define an Employee base class with name and base_salary, then a Manager subclass adding a bonus, with an overridden total_pay() that adds it to the base's calculation.
Decide between composition and inheritance for a Library that CONTAINS many Book objects (not "is-a" Book). Implement it using composition.
Define a Vehicle base class with make/model and a describe() method, then Car and Motorcycle subclasses each adding a type-specific attribute, both inheriting describe() unchanged.
Use abc.ABC and @abstractmethod to define a Shape abstract base class with an abstract area() method, then implement it in a Circle subclass.
Build a Person base class with name/age, then Student (adding school) and Teacher (adding subject) subclasses, each with their own introduce() override.
Build Dog, Cat, and Cow classes, each with a speak() method, and loop through a mixed list calling speak() on each — a "zoo" polymorphism demo.
Build a Car class composed of an Engine AND Wheels (two separate composed objects), delegating a start() call to both.
Build a Person class where age is a property with a setter that raises a ValueError for negative ages.
Build an Animal class with a sound class attribute default "...", and subclasses Dog/Cat each overriding just the class attribute (not a method) to change behavior.
Build a Shape class hierarchy: Rectangle base, with Square as a subclass that forces width == height in its own constructor.
Build an Order class composed of multiple Item objects (a list), with a total() method summing each item's price via delegation.
Build a Notification base class with a send() method printing a generic message, then EmailNotification and SMSNotification subclasses each overriding it with a specific format.
The following code crashes with a TypeError when creating a Dog. Find and fix the bug.
class Animal:
def __init__(self, name):
self.name = name
class Dog(Animal):
def __init__(self, name, breed):
self.breed = breed
my_dog = Dog("Rex", "Labrador")
print(my_dog.name)Build an Animal base class overriding __str__ to show "<ClassName>: <name>", and demonstrate that a Dog subclass inherits this formatting automatically.
Define Swimmer and Flyer classes each with their own method, then a Duck class inheriting from BOTH, able to call methods from each parent.
Given a simple diamond-shaped hierarchy (Base -> Left, Right -> Child(Left, Right)), print Child.__mro__ and explain which parent's method wins if both Left and Right define the same method.
Demonstrate that an abc.ABC class with an @abstractmethod CANNOT be instantiated directly, catching the resulting TypeError.
Add a @balance.deleter to a BankAccount's balance property, allowing del account.balance to reset it to 0 instead of actually deleting the attribute.
Build a 3-level hierarchy: LivingThing -> Animal -> Dog, each adding one attribute via super().__init__() chaining, and print all three attributes from a Dog instance.
Given a WRONGLY-inherited Car(Engine) class (a car "is-a" engine, which is conceptually wrong), refactor it into proper composition (Car HAS-A Engine).
Write a function print_total_area(shapes) that accepts ANY list of objects with an .area() method — regardless of their class — and sums the total, demonstrating duck typing.
Build a Discountable base class with apply_discount(price) returning price unchanged, and subclasses SeasonalSale (10% off) and ClearanceSale (50% off) each overriding it — then compute the final price for a product through each.
Build a SavingsAccount(BankAccount) subclass that overrides deposit() to also add interest automatically, calling super().deposit() for the base behavior first.
The following code silently produces the WRONG total because SavingsAccount.deposit() forgets to call the parent's version at all. Find and fix the bug.
class BankAccount:
def __init__(self, balance):
self.balance = balance
def deposit(self, amount):
self.balance += amount
class SavingsAccount(BankAccount):
def deposit(self, amount):
interest = amount * 0.05
self.balance += interest # forgot to add `amount` itself!
account = SavingsAccount(1000)
account.deposit(200)
print(account.balance)Build a "Zoo Simulation": an Animal base class and Lion/Elephant/Parrot subclasses each overriding speak(), held in one Zoo class that can make_all_speak() polymorphically.
Build an "Employee Management System": Employee base with calculate_pay(), and Manager/Developer subclasses each overriding it with their own formula, processed polymorphically in a payroll loop.
Build a "Shape Area Calculator": an abstract Shape base (using abc), with Circle, Square, and Triangle subclasses, computing and printing the total area of a mixed list.
Build a "Vehicle Rental System" using composition: a Vehicle class that HAS an Engine, with Car and Bike subclasses adding rental-rate logic.
Build a "Bank System" with BankAccount base and a SavingsAccount subclass that overrides deposit() to add interest, using encapsulated _balance and a read-only balance property throughout.
Explain the "favor composition over inheritance" principle, refactoring an over-inherited example (Duck(SwimmingThing)) into composition instead.
Explain why exposing a raw public attribute is riskier than a @property, demonstrating a scenario where validation logic added LATER via a property doesn't break any existing calling code.
Give the precise definition of polymorphism ("same interface, different implementations") and demonstrate it with three UNRELATED classes (no shared base class) that all just happen to define .area().
Explain why abstract base classes are useful for enforcing a contract across a team, demonstrating that forgetting to implement a required method produces an immediate, clear TypeError rather than a confusing bug much later.
Build an "OOP Mastery Report" — the most complete demonstration in this module. Design an abstract Employee base (inheritance + abstraction), Manager/Developer subclasses (overriding + super()), a Department class composed of employees (composition), an encapsulated _id with a read-only property, and a polymorphic loop printing every employee's pay.
Still stuck on something?
Book a free 1-on-1 session and we'll work through it together.
Book a Free Session