Implementing Inheritance
Let us implement some of our classes in our example. We will create a Character
class, and a Enemy
subclass that inherits from Character
. For simplicity, we will only implement a subset of the attributes and methods.
class Character:
def __init__(self, name, health=50, strength=30, defence=20):
self.name = name
self.health = health
self.strength = strength
self.defence = defence
def attack(self, character):
character.health = character.health - self.strength
print(f"Bam! {self.name} attacked {character.name}.",
f"{character.name}'s health is now {character.health}")
def defend(self, character):
self.health = self.health - character.strength * 0.25
print(f"{self.name} defended against {character.name}.",
f"{self.name}'s health is now {self.health}")
def __str__(self):
return f"{self.name} is a Character (health: {self.health},"\
f"strength: {self.strength}, defence: {self.defence})"
class Enemy(Character):
def __init__(self, name, health=50, strength=30, defence=20, evilness=50):
self.evilness = 50
# call the constructor of the superclass
super().__init__(name, health, strength, defence)
def evil_laugh(self):
print("Hehehehehe!")
def __str__(self):
return f"{self.name} is an Enemy (health: {self.health},"\
f"strength: {self.strength}, defence: {self.defence},"\
f"evilness: {self.evilness})"
boy = Character("Boy", 100, 20, 10)
evilman = Enemy("Voldemort", 30, 50, 40, 100)
print(boy)
print(evilman)
evilman.attack(boy)
boy.defend(evilman)
boy.evil_laugh() # You should get an error here.
super()
refers to the superclass - in this case it is Character
.
As you may have observed, Enemy
has fewer lines of code than Character
, despite being more powerful. We did not have to explictly define the attributes name
, health
, strength
and defence
in Enemy
. Enemy
inherits all these from Character
, thus a simple call to the constructor of the superclass is sufficient.
evilman
was also able to attack the poor boy
without having to explicitly define the attack()
method.
boy
cannot however express an evil_laugh()
because it neither implemented that method nor inherited that method from any superclass.
Method overriding
Let us now try to implement the Monster
class, and also let it have its own evil laughter rather than following the default laughter of Enemy
! 👾
class Monster(Enemy):
def __init__(self, name, health=50, strength=30, defence=20, evilness=50, smelliness=100):
self.smelliness = smelliness
super().__init__(name, health, strength, defence, evilness)
def evil_laugh(self):
print("WAHAHAHAHAHAHAHAHAHA!!! HA!!")
monster = Monster("Bigfoot", 100, 70, 40, 50, 1000)
monster.evil_laugh()
So, the monster now has its own customised evil laugh. WAHAHAHAHAHAHAHAHAHA!!! HA!!
This is called method overriding.