Ď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...
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.