Master Python inheritance with super(), method overriding, abstract classes, multiple inheritance, and Method Resolution Order (MRO).
📌 Python inheritance, OOP inheritance, super() Python, multiple inheritance, abstract classes, MRO Python
Inheritance is a fundamental OOP concept allowing creation of new classes based on existing ones. Child classes receive parent class attributes and methods while enabling extension and modification—representing an 'is-a' relationship where a dog IS an animal, a car IS a vehicle.
Inheritance delivers four key benefits: code reuse eliminates duplication, logical hierarchies reflect natural object relationships, extensibility facilitates new functionality addition, and polymorphism enables uniform object usage across different classes.
The super() function is essential for accessing parent class methods from child classes. It enables functionality extension rather than complete replacement, allowing child classes to build upon parent behavior while adding their own customizations.
Abstract classes serve as templates requiring subclass implementation. Using ABC (Abstract Base Class) with @abstractmethod decorator ensures child classes implement specified methods—perfect for defining interfaces that guarantee consistent behavior across subclasses.
Multiple inheritance allows classes to inherit from multiple parents, accessing methods from all sources. Python's Method Resolution Order (MRO) determines which parent method executes first when there are conflicts—displayed via __mro__ attribute.
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
return "Some sound"
class Dog(Animal):
def speak(self):
return "Woof!"
class Cat(Animal):
def speak(self):
return "Meow!"
dog = Dog("Buddy")
print(dog.name) # "Buddy" (inherited)
print(dog.speak()) # "Woof!" (overridden)class Vehicle:
def __init__(self, brand):
self.brand = brand
self.speed = 0
def accelerate(self, amount):
self.speed += amount
class Car(Vehicle):
def __init__(self, brand, fuel_type):
# Call parent __init__
super().__init__(brand)
self.fuel_type = fuel_type
def accelerate(self, amount):
# Extend parent behavior
super().accelerate(amount)
print(f"Speed: {self.speed} km/h")
my_car = Car("Toyota", "electric")
my_car.accelerate(50)
# Output: Speed: 50 km/hclass LivingThing:
def breathe(self):
return "Breathing..."
class Animal(LivingThing):
def move(self):
return "Moving..."
class Mammal(Animal):
def feed_young(self):
return "Feeding young..."
class Dog(Mammal):
def bark(self):
return "Woof!"
dog = Dog()
print(dog.breathe()) # From LivingThing
print(dog.move()) # From Animal
print(dog.feed_young()) # From Mammal
print(dog.bark()) # From Dogfrom abc import ABC, abstractmethod
class Shape(ABC):
@abstractmethod
def area(self):
"""Calculate area of the shape"""
pass
@abstractmethod
def perimeter(self):
"""Calculate perimeter of the shape"""
pass
class Rectangle(Shape):
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
def perimeter(self):
return 2 * (self.width + self.height)
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
return 3.14 * self.radius ** 2
def perimeter(self):
return 2 * 3.14 * self.radius
# rect = Shape() # Error - can't instantiate abstract class
rect = Rectangle(5, 3)
print(rect.area()) # 15class Flyable:
def fly(self):
return "Flying high!"
class Swimmable:
def swim(self):
return "Swimming gracefully!"
class Duck(Flyable, Swimmable):
def quack(self):
return "Quack!"
donald = Duck()
print(donald.fly()) # "Flying high!"
print(donald.swim()) # "Swimming gracefully!"
print(donald.quack()) # "Quack!"class A:
def method(self):
return "A"
class B(A):
def method(self):
return "B"
class C(A):
def method(self):
return "C"
class D(B, C):
pass
d = D()
print(d.method()) # "B" (B comes before C in inheritance)
# Check MRO
print(D.__mro__)
# (<class '__main__.D'>, <class '__main__.B'>,
# <class '__main__.C'>, <class '__main__.A'>,
# <class 'object'>)class Animal:
pass
class Dog(Animal):
pass
dog = Dog()
# isinstance checks object instances
print(isinstance(dog, Dog)) # True
print(isinstance(dog, Animal)) # True
print(isinstance(dog, object)) # True
# issubclass checks class relationships
print(issubclass(Dog, Animal)) # True
print(issubclass(Animal, Dog)) # False
print(issubclass(Dog, object)) # True