Chapter 2: Object interaction

Using other objects

face Josiah Wang

In object-oriented terms, hero.attack(enemy) is an example of a dependency relationship between two object instances.

In this example, hero.attack() takes another object (enemy) as an input argument, and can use any of the second object’s attributes/methods as necessary. Basically, hero is dependent on enemy because hero uses enemy, and can ask enemy to perform an action on its behalf (e.g. enemy.reduce_health()).

Here is a more concrete example of how the attack() method might be implemented for the Hero class.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
class Hero:
    def __init__(self, name, health, strength, defence, luck):
        self.name = name
        self.health = health
        self.strength = strength
        self.defence = defence
        self.luck = luck

    def attack(self, enemy):
        spell_power = self.cast_spell()
        attack_power = self.strength * spell_power
        enemy.reduce_health(attack_power)

    def cast_spell(self, spell_name="Expulso"):
        if spell_name == "Expulso":
            return 1.2
        else:
            return 1.0

The beauty is that the Hero instance does not need to know how an Enemy will reduce its own health. All it knows that enemy will reduce its health if its .reduce_health() method is invoked (Line 12). So hero only needs to ask enemy to do it (and trust that enemy will do what it is supposed to do)! The details of how this is done are abstracted from hero. Of course, if enemy decides to rename or remove the .reduce_health() method one day, then hero will also have to change it! This is why hero is considered to be dependent on enemy.

In a class diagram, dependency is often represented with a dashed line between two classes.

Class diagram for dependency