320 likes | 469 Views
Python - OOP. Dedovanje. Pogosto uporabljani postopki. Imamo razred Ulomek Denimo, da z ulomki zelo pogosto izvajamo določen postopek npr. jim spremenimo predznak Napišemo ustrezno funkcijo Vedno, ko želimo ulomkom spreminjati predznak, moramo napisati to funkcijo
E N D
Python - OOP Dedovanje
Pogosto uporabljani postopki • Imamo razred Ulomek • Denimo, da z ulomki zelo pogosto izvajamo določen postopek • npr. jim spremenimo predznak • Napišemo ustrezno funkcijo • Vedno, ko želimo ulomkom spreminjati predznak, moramo napisati to funkcijo • Naredimo iz nje knjižnico – "zaprimo v svoj razred" • Ampak to ni "objektno" • Znanje spreminjanja predznaka je lastno ulomku– objektu • Ulomek (objekt) naj bi znala spremeniti predznak • Odzvati se metodi spremeniPredznak: • nekUlomek.spremeniPredznak() • Ni problem, dopišemo metodo • Popravljati dobro preizkušen razred? • ... Do not fix, untilyou are completelydesperate …
Dedovanje • "razširjanje" objektov • Naredimo načrt za razred boljših ulomkov • Boljši: Znajo spremeniti predznak • classBoljsiUlomek(Ulomek) • Vsaka boljši ulomek "zna" vse, kar zna običajni ulomek iz razreda Ulomek in morda še kaj • Ima ista stanja/lastnosti • Morebiti tudi dodatna • Dedovanje • Izpeljani razred podeduje vse lastnosti • In vse metode
Razred BoljsiUlomek class BoljsiUlomek(Ulomek) : '''naredimonovrazred "boljših ulomkov" ''' defspremeniPredznak(self) : #Vsakaboljši ulomek si zna # spremeniti predznak pom = Ulomek(-1, 1) self.pomnoži(pom)# metoda pomnoži je podedovana iz razreda Ulomek
Uporaba Boljšega ulomka boUl = BoljsiUlomek(2,3) # "ustvarimo" boljši ulomek navadniUl = Ulomek(2, 3) # navadni ulomek #izpis boUl.izpis() # metoda izpis je podedovana! navadniUl.izpis() # spremenimo predznak navadnega ulomka navadniUl.pomnozi(Ulomek(-1,1)) # "čaramo" # spremenimo predznak 'boljšega' ulomka boUl.spremeniPredznak() #pri "boljših" ulomkih je zadevaelegantnejša #izpis boUl.izpis() navadniUl.izpis()
Dedovanje • Izpeljava novih razredov iz obstoječih • Uvajanje dodatnih metod • Lahko tudi dodatne lastnosti (podatki) • Primer: • matrike • Seštevanje, odštevanje, množenje • Kvadratne matrike / classKvMatrike(Matrike) • Ker je razred izpeljan – ni potrebno na novo pisati metod za seštevanje, odštevanje, množenje • Možne dodatne operacije • Inverz, deljenje, …
Dedovanje • Hierarhična zgradba razredov • Vrhnji objekt • object • Iz njega izpeljani vsi drugi razredi • Če ne napišemo classNovR(stRazred) … • classNovR : • classNovR(object) : • Razred object • Ima metodo __str__(self) • Zato jo "imajo" vsi razredi • Jo podedujejo • “specializacija” objektov • "razširjanje" razredov
Zajci dobijo imena • Kasneje ugotovimo, da bi bilo dobro za zajce voditi še njihovo starost. Dodamo še datum rojstva. • Prejšnjič – ko smo potrebovali ime, smo šli popravljati razred • Sedaj pa naredimo nov razred, razred Pametnih Zajcev, ki vedo, kdaj so rojeni! • In seveda znajo povedati, koliko so stari • Novi razred: • classPametniZajec(Zajec) :
Nove lastnosti • No, pravzaprav le ena – datumRojstva, ki bo tipa Datum • __init__ • Nastaviti tisto, kar počne __init__ v Zajec, in še nastaviti datum def __init__(self) : Zajec.__init__(self) # kličemo 'nadrejeni' konstruktor self.datumRoj = Datum()
__init__ • In kaj če na __init__ pozabimo? • Uporabi se podedovana! • Kaj pa, če je še nadrejeni razred nima • Jo zagotovo ima • Jo je podedoval iz object • Seveda je verjetno neuporabna (ne ve za lastnosti …)
Dedovanje • Sestavi razred Zlatnik, ki deduje iz razreda Kovanec. Zlatnik ima poleg osnovnih lastnosti kovanca podano še gostoto materiala, iz katerega je izdelan, čistočo zlata (podano z realnim številom med 0 in 1) in vrednost čistega zlata na masno enoto. Razred naj pozna tudi metodo Vrednost(), ki vrne vrednost zlatnika.
Dedovanje • "razširjanje" objektov • Naredimo načrt za razred Zlatnik • Kovanec s posebnimi lastnostmi • class Zlatnik(Kovanec) • Vsaka zlatnik "je in zna" vse, kar zna kovanec in morda še kaj • Vrednost čistega zlata je enaka za VSE zlatnike • razredna spremenljivka
Konstante • Mimogrede … • V razredu Kvader • MIN_DOL_STR = 1 • gre za konstanto • V Pythonu konstant načeloma ni • So le spremenljivke • Vedno lahko spremenimo • A dogovor – če je ime z velikimi črkami! • PUSTI PRI MIRU!!
Razredne spremenljivke/lastnosti • V nekaterih drugih jezikih • Statične spremenljivke • Enaka vrednost za vse objekte nekega razreda • Npr. minimalna in maksimalna teža zajca • Skupni del serijske številke • Definiramo jih izven vseh metod • …
Razredne lastnosti • Razredne /statične (ker niso vezane na objekt) lastnosti obstajajo neodvisno od obstoja objekta tega razreda • Le en primerek za cel razred! • Uporabimo tudi npr. za števec ustvarjenih objektov
Razredne spremenljivke classFoo : x = 42 def __init__(self, z) : self.y= z • x: statična lastnost, y: objektna (nestatična) lastnost • Statične lastnosti: vsebovane v razredu, objektne lastnosti: v objektih. • Vsak objekt vsebuje svojo kopijo objektnih lastnosti, vsaka statična lastnost pa vedno obstaja v eni sami kopiji. t1 = Foo(42) t2 = Foo(30) • Dva objekta - dve kopiji lastnosti y, po eno v vsakem objektu. Ker je lastnost x statična, vedno obstaja v eni sami kopiji, tudi če nimamo nobenih objektov razreda Foo:
Uporaba statičnih spremenljivk • Različne konstante • Enolična identifikacija • Objekt naj ima svojo serijsko številko • Denimo, da so te številke zaporedne • Vedeti, katera je bila dodeljena zadnja • Zadnja dodeljena številka: ni lastnost objekta, ampak cele skupine objektov • Vedno, ko je določen podatek skupen za vse objekte tega razreda • Kakovemo, alinajbolastnost statičnaaliobjektna? • Statičnelastnosti so tiste, ki so skupnezacelotenrazred – niso posebna lastnost enega (ali nekaj) primerkov objektov tega razreda.
Statične lastnosti - naslavljanje • Naslavljanje • ime_objekta.ime_lastnostiali ime_razreda.ime_lastnosti • Praviloma: ime_razreda.ime_lastnosti • Izogibamo seime_objekta.ime_lastnosti, saj ta lastnost ni vezana na objekt! • Ni potrebno, da bi sploh obstajal kak objekt te vrste
Zajec • Radi bi vedeli, koliko zajcev imamo • Števec ustvarjenih objektov • NI lastnost posameznega zajca • SKUPNA lastnost • kolikoZajcev= 0; • Na začetku 0 • Spreminjamo takrat, ko ustvarimo novega zajca • V konstruktorju! • Serijska številka naj bo zagotovo enolična • Določimo jo le enkrat – ob rojstvu (konstruktor) • ZAJEC_n (če je to n-ti zajec)
Zgled uporabe >>> >>> mZ = ZajecNov() >>> mZ.PovejSerijsko() 'ZAJEC_1' >>> ZajecNov.KolikoZajcev() 1 >>> tZ = ZajecNov() >>> tZ.PovejSerijsko() 'ZAJEC_2' >>> ZajecNov.KolikoZajcev() 2 >>>
ZajecNov class ZajecNov : # SKUPNE KONSTANTE OSNOVA_SERIJSKA = "ZAJEC_" MIN_TEŽA = 0 # minimalnateža MAX_TEŽA = 10 # maksimalnateža # SKUPNE SPREMENLJIVKE kolikoZajcev = 0
ZajecNov # konstruktor def __init__(self, sp = True, teža = 1.0) : self.spol = sp if teža <= ZajecNov.MIN_TEŽA : raise Exception('ne moremustvaritizajca s težo ' + str(teža)) if teža > ZajecNov.MAX_TEŽA : raise Exception('Zajec je pretežak: ' + str(teža)) # česmotu, je teža med MIN_TEŽA in MAX_TEŽA self.masa = teža # naredilismonovegazajca, povečamoštevilo ZajecNov.kolikoZajcev += 1 # določimoseriskoštevilko self.serijska = ZajecNov.OSNOVA_SERIJSKA + str(ZajecNov.kolikoZajcev)
ZajecNov # get/set metode def PovejTezo(self) : # težobomopovedali le na 0.5 kg natančno tezaKg = int(self.masa) decim = int((self.masa - tezaKg) * 10) if decim < 3 : return tezaKg + 0.0 if decim < 8 : return tezaKg + 0.5 return tezaKg + 1.0 def SpremeniTezo(self, novaTeza) : # smislena nova teza je le med MIN_TEŽA in MAX_TEŽA if MIN_TEŽA < novaTeza <= MAX_TEŽA : self.masa = novaTeza; return True # spremembauspela # v nasprotnemprimeru NE spremenimoteže # in javimo, daspremembenismonaredili return False def PovejSerijsko(self) : return self.serijska;
ZajecNov def KolikoZajcev() : return ZajecNov.kolikoZajcev # def SpremeniSerijsko(self, s) : serijska se ne spremeni!!! def PovejIme(self): return self.ime def JeSamec(self) : return self.spol # ker se spolnaknadno NE spremeni, metodeza # spreminjanjespolasploh ne ponudimouporabniku!
Dedovanje • Sestavi razred Zlatnik, ki deduje iz razreda Kovanec. Zlatnik ima poleg osnovnih lastnosti kovanca podano še gostoto materiala, iz katerega je izdelan, čistočo zlata (podano z realnim številom med 0 in 1) in vrednost čistega zlata na masno enoto. Razred naj pozna tudi metodo Vrednost(), ki vrne vrednost zlatnika.
Zlatnik class Zlatnik(Kovanec) # razredne spremenljivke definiramo izven __init__ vrednostCistegaZlata = 125.4 # za vse zlatnike je to enako! def __init__(self, r, v, g, č) : Kovanec.__init__(self, r, v) # nastavimo polmer invisina self.gostota = g self.cistost = č # "SET" metode nastaviPolmer(self, r) # podedovana nastaviVisino(self, visina) # podedovana defnastaviGostoto(self, x) : defnastaviCistost(self, x) : defnastaviVrednostCistegaZlata(v) # vrednost lahko spreminjamo tudi, # če še ni nobenega zlatnika! # "GET" metode povejPolmer(self) # podedovana povejVisino(self) # podedovana defpovejGostoto(self) defpovejCistost(self) defpovejVrednostCistegaZlata(self) # vrednost lahko zvemo tudi, # če še ni nobenega zlatnika! # str def __str__(self) # podedovana str metoda nam ne ustreza! # "znanje" volumen(self) # podedovana povrsina(self) # podedovana def vrednost(self)
Iz muhe slon • Ne, iz muhe ne bomo naredili slona, ampak pri nas zajci postanejo ovce • Pri nas se je oglasil bogati Rus, ki je bil tako navdušen nad našim programom za vodenje farme zajcev, da hoče, da mu zanj pripravimo podoben program • Posebno nad metodo meNapojiti() je bil navdušen! • A žal on ne vodi farme zajcev, ampak farmo ovac. • Poleg tega, da ovce redi za zakol, prodaja tudi njihove kožuhe, zato bi rad, da vodimo še barvo njihovega kožuha.
Osnova: razred ZajecNov • Kakšne spremembe so potrebne • Napačne lastnosti • OSNOVA_SERIJSKA ni OK • Prav tako MAX_TEZA • Dodati lastnosti • Barva kožuha • Get/set metodi • denimo, da si tudi ovce barvajo kožuhe • Popraviti konstruktor • Dodati metodo __str__ • V razredu ZajecNov smo nanjo pozabili!
Prekrite metode • V predniku (neposrednem ali posrednem) definirana metoda nam ne ustreza • Predefiniranje: prekrite metode • Overriding • Enaka metoda kot pri predniku – velja naša definicija
Zgled • Urejen seznam • Denimo, da velikokrat potrebujemo sezname, ki so urejeni • Nobenih dodatnih lastnosti • Dodatne metode • SPREMENJENE metode