Inheritance And Polymorphism
Inheritance lets a child class reuse and extend the behavior of a parent class.
class SavingAccount(BankAccount):
passThe child has the parent functionality plus any extra functionality it defines.
Constructor Customization
A child class can call the parent constructor, then add its own attributes.
class SavingAccount(BankAccount):
def __init__(self, balance, interest_rate):
BankAccount.__init__(self, balance)
self.interest_rate = interest_rateIn modern Python, super() is usually preferred when the inheritance hierarchy is more complex.
Method Overriding
A child class can override a parent method to customize behavior.
class Manager(Employee):
def give_raise(self, amount, bonus=1.05):
Employee.give_raise(self, amount * bonus)Polymorphism
Polymorphism means using a common interface across different classes. Code can call the same method on different object types when those objects support the expected behavior.
Liskov Substitution Principle
The Liskov Substitution Principle says a base class should be replaceable by any subclass without breaking program behavior.
Violation examples:
- subclass method requires extra parameters
- subclass strengthens input conditions
- subclass weakens output guarantees
- subclass throws additional unexpected exceptions
- subclass changes unrelated state
The square-rectangle problem is a classic violation. A square may seem like a rectangle mathematically, but if setting width and height independently is part of the rectangle interface, a square cannot safely substitute for a rectangle.
This connects to Dependency Injection because composition is often safer than inheritance when substitutability is unclear.