Někdy nám pro tvorbu aplikace nestačí už jen nástroje strukturovaného programování (dělení programu metodou top-down na dílčí podprogramy), ale potřebujeme problém vyřešit objektovou cestou. Programovací jazyk Python objekty přirozeně podporuje, v zásadě všechny proměnné v Pythonu jsou objekty.
Objektem modelujeme nějaký prvek reálného světa. Tak jako jsme pro modelování problémů používali doposud proměnné jednoduchých (int, float) nebo složených datových typů (str, pole, slovník) a manipulaci s nimi obstarával program, v objektově orientovaném programování tyto dvě části (data a programy) začleníme do jedné struktury, do objektu.
Předlohou pro konkrétní objekty s konkrétními daty bude třída (angl. class). V rámci třídy definujeme
- vnitřní objektové proměnné, tzv. atributy
- a dílčí funkce a procedury pro práci s atributy, tzv. metody.
Takto vypadá definice třídy:
class DopravniProstredek: # definice třídy objektů def nastav(self, pk, zn, tp): # metoda objektu s parametry self.pocetkol = pk # atribut objektu nastavený parametrem self.znacka = zn # další atribut objektu self.typ = tp # další atribut objektu def cojsemzac(self): # metoda objektu print(self.typ, self.znacka, self.pocetkol)
Konkrétní objekty, tzv. instance, vytvoříme voláním funkce se stejným jménem, jako má příslušná třída. K atributům se dostaneme pomocí tečky za identifikátorem objektu a jménem atributu, úplně stejně při volání příslušné metody:
Auto = DopravniProstredek() # vytvoří instanci (objekt) třídy Kolo = DopravniProstredek() # vytvoří jiný objekt téže třídy Auto.pocetkol = 4 # nastaví atribut prvního objektu Auto.typ = "automobil" # nastaví druhý atribut prvního objektu Kolo.nastav(2, "bycikl") # nastaví atributy 2. objektu metodou Auto.cojsemzac() # volá metodu prvního objektu Kolo.cojsemzac() # volá metodu druhého objektu Auto.palivo = "N95" # dynamicky přidá další atribut
Na uvedeném příkladu je vidět, že objekty (instance) stejné třídy mají stejné metody, ve výchozím stavu i stejné atributy (stejně pojmenované proměnné), nicméně s různými hodnotami. Další atributy můžeme přidávat i mimo definici třídy, nicméně tím přijdeme o mnoho výhod objektového programování.
Zapouzdření dat a algoritmů do objektu
Vlastnost objektů, kde spojujeme proměnné a obslužné funkce do objektu, se nazývá zapouzdření. Spolu s dědičností a polymorfismem, které si vysvětlíme později, tvoří silný nástroj pro modelování objektů reálného i virtuálního světa.
V Pythonu k definici třídy objektů používáme klíčové slovo class
, metody dané třídy pak opět odsazujeme o stejný počet mezer. Jako první parametr dané metody uvádíme klíčové slovo self
, které danému objektu poskytuje odkaz na vlastní instanci.
Atributy třídy deklarujeme dynamicky v metodách právě se prefixem self.
jako běžné proměnné. Klidně si self přeložte jako „můj“, „moje“. Deklarace self.atribut
pak znamená „můj konkrétní atribut“ (říká si konkrétní objekt, instance). Pokud uvnitř deklarace metody použijete proměnnou bez prefixu self
, jde o běžnou lokální proměnnou funkce.
Konstruktor __init__()
Typickým místem, kde definujeme poprvé atributy objektu, je speciální metoda zvaná konstruktor. Ten se volá automaticky pokaždé, když objekt vytváříme pomocí konstrukce
NovyObjekt = NazevTridy()
I když jsme ho sami nedefinovali, Python převezme a zavolá konstruktor implicitní, při němž vytvoří objekt a vše potřebné k němu. Obecně je ale lepší vytvořit si konstruktor vlastní, který nám umožní si objekt připravit přesně tak, jak potřebujeme.
Když bychom si vzali předchozí příklad, na konstruktor by se nám skvěle hodila metoda nastav(). V podstatě stačí, když ji přejmenujeme na __init__
. Ta dvě podtržítka před a za init jsou důležitá, jejich přesný význam si řekneme později.
class DopravniProstredek: # definice třídy objektů def __init__(self, pk, zn, tp): # konstruktor objektu s parametry self.pocetkol = pk # atribut objektu nastavený parametrem self.znacka = zn # další atribut objektu self.typ = tp # další atribut objektu def cojsemzac(self): # metoda objektu print(self.typ, self.znacka, self.pocetkol) Motorka = DopravniProstredek(2, "Jawa", "motokolo") # vytvoření objektu Motorka.cojsemzac() # konstruktorem
Jako příklad si nakreslíme tři domečky s oknem s využitím knihovny TKinter. Přitom si vytvoříme třídu Domecek jako předlohu pro budoucí objekty, která nám zapouzdří jak atributy (souřadnice, barvu domečku a odkaz na plátno, na které kreslíme) tak i konstruktor a metodu na vykreslení.
Tři domečky pomocí objektů
import tkinter as tk root = tk.Tk() WIDTH = 600 HEIGHT = 400 platno = tk.Canvas(root, width=WIDTH, height=HEIGHT) platno.pack() # definice třídy pro krabičku na jednotlivé objekty class Domecek(): def __init__(self, xplatno, xx, yy, barva): # konstruktor self.platno = xplatno self.x = xx self.y = yy self.barva = barva def kresli(self): # metoda pro vykreslení self.platno.create_rectangle(self.x, self.y, self.x+100, self.y+100, fill=self.barva) self.platno.create_polygon(self.x, self.y, self.x+50, self.y-50, self.x+100, self.y, fill=self.barva, outline="black") self.platno.create_rectangle(self.x+30, self.y+30, self.x+70, self.y+70, fill="white") self.platno.create_line(self.x+40, self.y+30, self.x+40, self.y+70) self.platno.create_line(self.x+30, self.y+45, self.x+70, self.y+45) # vytvoříme tři domy dum1 = Domecek(platno, 60, 220, "red") dum2 = Domecek(platno, 220, 220, "green") dum3 = Domecek(platno, 380, 130, "yellow") # vytvořené objekty nakreslíme dum1.kresli() dum2.kresli() dum3.kresli() root.mainloop()
Výstupem programu bude následující grafické okno s nakreslenými domečky:
Další:
- vše v Pythonu jsou objekty
- dědičnost, polymorfismus
- veřejné, chráněné a soukromé atributy, atributy objektu a třídy
Přidejte odpověď
Pro přidávání komentářů se musíte nejdříve přihlásit.