testovac.sk

Inheritence

Ďalším zo základných princípov Objektovo Orientovaného Programovania (OOP) je tzv. inheritence, po slovensky "dedičnosť" (dedenie). Tento princíp hovorí o tom, že v prípade, keď rôzne triedy majú spoločné atribúty alebo (a) metódy, dá sa pre ne vytvoriť nadtrieda (rodič), v ktorej budú tieto rovnaké atribúty a metódy implementované. Pôvodné triedy budú potom prehlásené za potomkov (deti) tejto nadtriedy, čím zdedia jej atribúty a metódy, teda ich nebude nutné definovať v každej podtriede zvlášť, ale stačí len raz, v ich spoločnej nadtriede. Každá podtrieda môže mať navyše k zdedeným aj svoje vlastné atribúty a metódy, hovoríme, že podtrieda rozširuje nadtreidu.

Praktická ukážka...

príklad - Geometrické tvary

Každý geometrický tvar má svoju polohu v ploche (súradnice x a y. Každým tvarom možno pohnúť - stačí zmeniť súradnice vyjadrujúce polohu. Obdĺžnik má navyše k polohe dva atribúty - veľkosti dvoch strán a a b, kruh má len jeden - polomer r.

Triedy pre tieto dva útvary by mohli vyzerať takto:

class Obdlznik():

    def __init__(self, x, y, a, b):
        self.x = x
        self.y = y
        self.a = a
        self.b = b

    def move(self, x, y):
        self.x = x
        self.y = y

    def set_rozmery(self, a, b):
        if a > 0 and b > 0:
            self.a, self.b = a, b


class Kruh():

    def __init__(self, x, y, r):
        self.x = x
        self.y = y
        self.r = r

    def move(self, x, y):
        self.x = x
        self.y = y

    def set_polomer(self, r):
        if r > 0:
            self.r = r

Vidíme, že útvary majú niekoľko atribútov rovnakých (x a y) a majú aj spoločnú metódu (move). Je dokonca možné predpokladať, že aj ďalšie tvary (štvorec, trojuholník, lichobežník, kosoštvorec) by mali takéto atribúty a metódy. Vytvorme teda nadtriedu Utvar a tieto spoločné atribúty a metódy presuňme tam:

class Utvar():

    def __init__(self, x, y):
        self.x = x
        self.y = y

    def move(self, x, y):
        self.x = x
        self.y = y


class Obdlznik(Utvar):  # 'Obdlznik' dedí z triedy 'Utvar'

    def __init__(self, x, y, a, b):
        super().__init__(x, y)  # volanie konštruktora nadtriedy
        self.a = a
        self.b = b

    def set_rozmery(self, a, b):
        if a > 0 and b > 0:
            self.a, self.b = a, b


class Kruh(Utvar):  # 'Kruh' dedí z triedy 'Utvar'

    def __init__(self, x, y, r):
        super().__init__(x, y)  # volanie konštruktora nadtriedy
        self.r = r

    def set_polomer(self, r):
        if r > 0:
            self.r = r 
  

o1 = Obdlznik(100,200,50,60) # voláme konštruktor triedy Obdlznik
k1 = Kruh(10,10,5)           # voláme konštruktor triedy Kruh
o1.move(200,300) # zdedená metóda z triedy Utvar
k1.move(210,310) # zdedená metóda z triedy Utvar

super()
V metódach potomka (podtriedy) môžeme používať vstavanú funkciu super(), ktorá referuje k nadtriede. Takto je možné vyvolať (spustiť) aj metódy nadtriedy, špeciálne volaním super().__init__() spustíme konštruktor nadtriedy, ktorý v našom prípade rieši vytvorenie atribútov x a y.


private __ vs protected _
Zákon káže: V metódach potomka (podtriedy) môžeme cez self pristúpiť k protected atribútom definovaným v predkovi ale nie k private atribútom predka.