Lesson 3 · OKSTEM College · Associate of Science in Computer Science
Inheritance Basics
Inheritance lets a child class reuse code from a parent class. The child gets all the parent's methods and attributes for free, and can add or override them.
classAnimal:
def__init__(self, name):
self.name = name
defspeak(self):
raiseNotImplementedError("subclass must implement speak()")
def__str__(self):
returnf"{self.__class__.__name__} named {self.name}"classDog(Animal): # Dog inherits from Animaldefspeak(self):
return"Woof!"classCat(Animal):
defspeak(self):
return"Meow!"print(Dog("Rex").speak()) # Woof!print(Cat("Luna").speak()) # Meow!
super() — Calling the Parent
super() gives you a proxy to the parent class. Use it in __init__ to run the parent's constructor before adding child-specific setup.
classVehicle:
def__init__(self, make, speed):
self.make = make
self.speed = speed
classElectricCar(Vehicle):
def__init__(self, make, speed, battery_kwh):
super().__init__(make, speed) # run Vehicle.__init__ firstself.battery_kwh = battery_kwh # then add child statedefrange_km(self):
returnself.battery_kwh * 6
tesla = ElectricCar("Tesla", 250, 100)
print(tesla.range_km()) # 600
Always call super().__init__() in a child class unless you deliberately want to skip parent initialization. Forgetting it is a common source of missing-attribute bugs.
Method Resolution Order (MRO)
When Python looks up a method it follows the MRO — a deterministic order across the inheritance chain. Use ClassName.__mro__ to inspect it.
2. What does super().__init__() do, and when would omitting it cause a bug?
It calls the parent class __init__, setting up parent-defined instance variables.
Omitting it means self.parent_attr never gets set — any method
that reads that attribute raises AttributeError at runtime.
Knowledge Check
Inheritance is declared in Python by
That's not valid Python syntax.
Correct — the parent class goes in parentheses after the class name.
No such built-in; that's Java/JS style.
No such decorator exists in Python.
Recap: class Child(Parent): is all you need. Python automatically searches the parent for any attribute not found on the child.
super().__init__() should be called
Call it first so parent attributes exist before child code uses them.
Correct — run the parent constructor first, then add child-specific state.
super() is used in concrete classes too.
super() goes up one level in the MRO; it doesn't recurse.
Recap: calling super().__init__() first ensures parent attributes are initialized before your child code touches them.
The MRO determines
MRO is about lookup order, not speed.
Privacy is controlled by naming conventions, not MRO.
Correct — Python walks the MRO left-to-right until it finds the method.
Parameter order is determined by the method signature, not MRO.
Recap: MRO = Method Resolution Order. Inspect it with ClassName.__mro__. Python finds the first match walking left-to-right down the chain.
If Dog inherits from Animal and both define speak(), calling dog.speak() uses
Correct — the child's method shadows the parent's.
Python uses the most-derived class's definition.
Methods don't merge; the child's wins unless you call super().
Both classes define speak(), so no error occurs.
Recap: method overriding — the child's definition wins. Use super().speak() if you also want to run the parent's version.
issubclass(Dog, Animal) returns
Correct — issubclass() checks the full inheritance chain.
It returns True for indirect subclasses too.
Method overriding is unrelated to issubclass().
issubclass() returns a boolean; __mro__ gives the list.
Recap: issubclass(Child, Parent) → True. isinstance(obj, Parent) → True if obj's class is Parent or any subclass.