Subclassing, super(), and method overriding
class Animal:
def __init__(self, name, sound):
self.name = name
self.sound = sound
def speak(self):
print(f"{self.name} says {self.sound}!")
class Dog(Animal): # Dog inherits from Animal
def fetch(self):
print(f"{self.name} fetches the ball!")
class Cat(Animal): # Cat inherits from Animal
def purr(self):
print(f"{self.name} purrs...")
rex = Dog("Rex", "Woof")
rex.speak() # Rex says Woof! (inherited from Animal)
rex.fetch() # Rex fetches the ball! (Dog-only method)
luna = Cat("Luna", "Meow")
luna.speak() # Luna says Meow! (inherited from Animal)
luna.purr() # Luna purrs... (Cat-only method)class Animal:
def __init__(self, name):
self.name = name
def describe(self):
return f"Animal: {self.name}"
class Dog(Animal):
def __init__(self, name, breed):
super().__init__(name) # Call parent's __init__
self.breed = breed # Add new attribute
def describe(self): # Override parent's method
return f"Dog: {self.name} ({self.breed})"
rex = Dog("Rex", "German Shepherd")
print(rex.describe()) # Dog: Rex (German Shepherd)super() calls the parent class's version of a method. Use it in __init__ when you want to keep the parent's setup and add to it. Forgetting super().__init__() means the parent's attributes never get created.class Character:
def __init__(self, name, hp):
self.name = name
self.hp = hp
def take_damage(self, amount):
self.hp -= amount
if self.hp <= 0:
self.hp = 0
print(f"{self.name} has been defeated!")
else:
print(f"{self.name} takes {amount} damage. HP: {self.hp}")
def __str__(self):
return f"{self.name} (HP: {self.hp})"
class Warrior(Character):
def __init__(self, name):
super().__init__(name, hp=150) # Warriors get more HP
self.armor = 10
def take_damage(self, amount):
reduced = max(0, amount - self.armor) # Armor reduces damage
print(f"{self.name}'s armor blocks {amount - reduced} damage!")
super().take_damage(reduced) # Call parent's take_damage
class Mage(Character):
def __init__(self, name):
super().__init__(name, hp=80) # Mages are fragile
self.mana = 100
def cast_spell(self, target, damage):
if self.mana >= 20:
self.mana -= 20
print(f"{self.name} casts a fireball!")
target.take_damage(damage)
else:
print("Not enough mana!")
w = Warrior("Kael")
m = Mage("Lyra")
print(w) # Kael (HP: 150)
m.cast_spell(w, 30)
print(w) # Kael (HP: 130) — armor blocked someisinstance() and issubclass():print(isinstance(w, Warrior)) # True
print(isinstance(w, Character)) # True (Warrior IS a Character)
print(isinstance(w, Mage)) # False
print(issubclass(Warrior, Character)) # True
print(issubclass(Mage, Character)) # TrueUsing the `Character` base class, create: 1. A `Warrior` subclass with extra `armor` attribute and overridden `take_damage` that reduces damage by armor 2. A `Healer` subclass with a `heal(target, amount)` method that increases a target's HP Use `super()` in both subclasses' `__init__`.
loading editor...
Ask about Inheritance
◇
Hey! I'm your AI tutor.
Ask me anything about this lesson, or paste code you're stuck on.
AI tutor is a premium feature