Kódím.cz
3

Dědičnost

V objektově orientovaném programování existuje důležitý pojem, kterým je dědičnost. Podíváme se, jak funguje.

Dědičnost

Třídy mají jednu zajímavou vlastnost - mohou od sebe dědit. Uvažujme třeba, že bychom chtěli vytvořit novou třídu Manager, která reprezentuje zaměstnance, který má nějaké podřízené. U manažera (manažerky) bychom rádi evidovali počet jeho/jejích podřízených. Dále předpokládáme, že manažeři a manažerky mají k dispozici služební auto a my evidujeme informace o autě jako řetězec. Jinak se samozřejmě manažer od ostatních nijak neliší - má jméno, pozici i nárok na dovolenou.

Ideální by tedy bylo mít kopii třídy Employee, která bude mít nový atribut subordinates (seznam jeho podřízených). Samozřejmě bychom mohli kód třídy Employee zkopírovat a upravit, ale díky dědičnosti to můžeme udělat i efektivněji. Můžeme novou třídu Manager postavit na základě třídy Employee. Třída Manager tak zdědí od třídy Employee všechny atributy a metody, a my jen přidáme nebo upravíme, co potřebujeme.

Napíšeme tedy novou funkci __init__, protože potřebujeme vytvořit atribut subordinates.

# Do závorek píšeme, od jaké třídy dědíme
class Manager(Employee):
    def __init__(self, name, position, holiday_entitlement, subordinates, car):
        self.name = name
        self.position = position
        self.holiday_entitlement = holiday_entitlement
        self.subordinates = subordinates
        self.car = car

Zkusíme si nyní vytvořit objekt, který bude reprezentovat manažera. U objektu vyzkoušíme, zda u ní funguje metoda __str__. Tuto metodu jsme pro třídu Manager neprogramovali, měla by být zděděná od třídy Employee.

marian = Manager("Marian Přísný", "vedoucí konstrukčního oddělení", 25, 2, "Škoda Octavia 1.5 TSI")
print(marian)

Zatím vše funguje, přesto můžeme náš kód ještě vylepšit. Ve funkci __init__ musíme poněkud nešikovně opisovat tři řádky, které nastavují hodnoty atributů. Přitom ty stejné řádky už jsou v třídě Employee. Mohli bychom nějak existující kód z třídy Employee upravit?

Ve skutečnosti ano. Využijeme k tomu speciální funkci super(), kterou se odvoláme na mateřskou třídu aktuální třídy. Následně můžeme použít tečku a zavolat funkci __init__. Tím tedy voláme funkci __init()__ mateřské třídy Employee.

class Manager(Employee):
    def __init__(self, name, position, holiday_entitlement, subordinates, car):
        # Volám metodu __init__() mateřské třídy
        super().__init__(name, position)
        self.subordinates = subordinates
        self.car = car

Pojďme ještě upravit výpis informace pomocí metody __str__. U třídy Manager budeme chtít do výpisu přidat informaci o tom, kolik má manažer podřízených (auto přidávat nebudeme). Opět můžeme pomocí funkce super() zavolat metodu __str__ z mateřské třídy Employee a připojit k ní větu o počtu podřízených.

class Manager(Employee):
    def __init__(self, name, position, holiday_entitlement, subordinates, car):
        super().__init__(name, position, holiday_entitlement)
        self.subordinates = subordinates
        self.car = car

    def __str__(self):
        # Volám metodu __str__() mateřské třídy a k výsledku přidávám další řetězec
        return super().__str__() + f" Má {self.subordinates} podřízených."

Vyzkoušíme znovu dvojici příkazů, kterou jsme zkoušeli předtím.

marian = Manager("Marian Přísný", "vedoucí konstrukčního oddělení", 25, 2, "Škoda Octavia")
print(marian)

Výsledkem je text:

Marian Přísný pracuje na pozici vedoucí konstrukčního oddělení. Má 2 podřízených.

Cvičení: Dědičnost

Bonusy