Inheritance lets a class reuse code from another class. A Dog and a Cat both inherit from Animal — they share eat() and sleep() but have their own speak(). Polymorphism means different classes can respond to the same method call differently.
Key Concepts
Inheritance
class Dog(Animal): Dog inherits all attributes and methods from Animal. Use super().__init__() to call the parent's __init__. Override methods to change behavior.
Method Overriding
If Dog defines its own speak() method, it overrides the parent's version. Calling dog.speak() runs the Dog version, not Animal.speak().
Polymorphism
for animal in [Dog(), Cat(), Bird()]: animal.speak() Each object responds to speak() in its own way. One interface, many implementations.
isinstance() and type()
isinstance(obj, Dog) → True if obj is a Dog or a subclass. type(obj) → exact class. Useful for checking types at runtime.
class Animal:
def __init__(self, name, age):
self.name = name
self.age = age
def speak(self):
return "..."
def __str__(self):
return f"{self.name} ({type(self).__name__}, age {self.age})"
class Dog(Animal):
def speak(self):
return "Woof!"
def fetch(self):
return f"{self.name} fetches the ball!"
class Cat(Animal):
def speak(self):
return "Meow!"
class Parrot(Animal):
def __init__(self, name, age, phrase):
super().__init__(name, age)
self.phrase = phrase
def speak(self):
return self.phrase
animals = [
Dog("Rex", 3),
Cat("Whiskers", 5),
Parrot("Polly", 2, "Pieces of eight!"),
Dog("Buddy", 1),
]
print("=== Animal Shelter ===")
for a in animals:
print(f"{a} says: {a.speak()}")
dogs = [a for a in animals if isinstance(a, Dog)]
print(f"\nDogs: {len(dogs)}")
for d in dogs:
print(f" {d.fetch()}")