170 likes | 331 Views
Python – OOP . Načini dostopa. Dostop do stanj objekta. Možnost, da neposredno dostopamo do stanj/lastnosti objekta NI NAJBOLJŠI ! Ne le, da ni najboljši, je == CENZURA == Nobene kontrole nad pravilnostjo podatkov o objektu! rjavko.masa = -3.2;
E N D
Python – OOP Načini dostopa
Dostop do stanj objekta • Možnost, da neposredno dostopamo do stanj/lastnosti objekta NI NAJBOLJŠI! • Ne le, da ni najboljši, je == CENZURA == • Nobene kontrole nad pravilnostjo podatkov o objektu! • rjavko.masa = -3.2; • Ker ne moremo vedeti, ali so podatki pravilni -vsi postopki po nepotrebnem bolj zapleteni • Objekt naj sam poskrbi, da bo v pravilnem stanju • Težave, če moramo kasneje spremeniti način predstavitve podatkov o objektu
Dostopi do stanj • ime_objekta.stanje • Zakaj je to lahko problem? • “zunanji” uporabnik nastavi napačno vrednost • z1.masa = -100.10 • Uporabnik pozna predstavitev • Kasneje je ni mogoče spremeniti
Dostop do stanj/lastnost • Kako uporabiti: • Metode za dostop do stanj • "get" metode • Metode za nastavljanje stanj • "set" metode • Zakaj je boljši dostop preko metod kot neposredno • Možnost kontrole pravilnosti! • Možnost kasnejše spremembe načina predstavitve (hranjenja podatkov) • Možnost oblikovanja pogleda na podatke • Podatke uporabniku posredujemo drugače, kot jih hranimo • Dostop do določenih lastnosti lahko omejimo • Npr. spol lahko nastavimo le, ko naredimo objekt (kasneje ne, saj se ne spreminja ... če odmislimo kakšne operacije, določene vrste živali ...) • Hranimo lahko tudi določene podatke, ki jih uporabnik sploh ne potrebuje ..
Dostop do stanj • Python žal ne omogoča, da bi preprečili neposreden dostop do spremenljivk • To načeloma ni povsem res (property), a ... • Določeni drugi jeziki (java, C# ...) vsebujejo ustrezne ukaze • Vendar se kljub temu lahko "obnašamo" lepo
Dostop do stanj • Zakaj ne uporabljamo neposrednega dostopa do stanj • uporabnika ne zanima, kako so podatki predstavljeni • Ko prestaviš iz 3 v 4 prestavo, te ne zanima, kako so prestave realizirane. Zanima te le to, da se stanje avtomobila (prestava) spremeni. • Sprememba tehnologije – za uporabnika se stvar ne spremeni • Denimo, da so v Pythonu11.5 spremenili način hranjenja podatkov v objektih razreda list • Ni potrebno spreminjati programov, ki razred list uporabljajo • Zaščita pred nedovoljenimi stanji • Neposreden dostop – uporabnik lahko neposredno dostopa in objekt spravi v nemogoče stanje • mojAvto.prestava = -10
Dostop do stanj/lastnosti: nastavitve • Nastavitve stanj • “prireditveni stavek” • zajček.spremeniTezo(2.5) • V bistvu isto kot zajček.masa = 2.5 • A metoda spremeniTezo lahko PREVERI, če je taka sprememba teže smiselna! • zajček.spremeniTezo(-12.5) • V bistvu isto kot zajček.masa = -12.5 • A tu bomo lahko PREPREČILI postavitev lastnosti objekta v napačno stanje!
Dostop do stanj • Poizvedba • “spremenljivka” v izrazu • zajček.povejTezo() • Da bomo lahko izvedeli težo zajca • Najenostavneje v telesu metode lereturnself.masa • Lahko stvar "oblikujemo" – recimo, da bomo uporabniku vedno povedali le težo na pol kilograma, mi pa bomo interno stvar vodili natančneje
Razred Zajec - spremeniTezo defspremeniTezo(self, novaTeza) : # smislena nova teza je le med 0 in 10 kg if0 < novaTeza <= 10 :self.masa = novaTeza # v nasprotnem primeru NE spremenimo teže ALI (obeh ne moremo imeti!) defspremeniTezo(self, novaTeza) : # smislena nova teza je le med 0 in 10 kg if0 < novaTeza <= 10 : self.masa= novaTeza returnTrue # sprememba uspela # v nasprotnem primeru NE spremenimo teže # in javimo, da spremembe nismo naredili returnFalse
spremeniTezo • Metoda je seveda lahko bolj kompleksna – denimo vemo, da se teža ne more spremeniti bolj kot za 15% defspremeniTezo(self, novaTeza) : # smislena nova teza je le med 0 in 10 kg # in če ni več kot 15% spremembe od zadnjič spM = self.masa * 0.85 zgM = self.masa * 1.15 if 0 < novaTeza <= 10 andspM < novaTeza <= zgM :self.masa = novaTeza returnTrue # sprememba uspela # v nasprotnem primeru NE spremenimo teže # in javimo, da spremembe nismo naredili returnFalse • Seveda je smiselno, da zagotovimo, da je teža ustrezna že ves čas! • Pozor na začetno stanje: konstruktor! • Tudi v konstruktorju preverimo, če se uporabnik "obnaša lepo"
Razred Zajec - povejTezo defpovejTezo(self) : returnself.masa • Ali pa prilagodimo podatke • Težo povemo na 0.5 kg natančno "po naše" • 2.721 2.5, 2.905 3, 2.502 2.5, 2,777 -> 2.5 ... • Vzamemo težo v celih kg in pogledamo prvo decimalko decimalnega dela • Če je med 3 in 7, prištejemo k celim kg 0.5 • Če je več kot 7, prištejemo k celim kg 1.0 defpovejTezo(self) : # težo bomo povedali le na 0.5 kg natančno # z malce drugačnim zaokroževanjem tezaKg = int(self.masa) decim = int((self.masa–tezaKg) * 10) if (decim < 3) : returntezaKg + 0.0 if (decim < 8) : returntezaKg + 0.5 returntezaKg + 1.0
Celotni razred Zajec - 1 class Zajec : def __init__ (self, serijskaStev = "NEDOLOČENO", spol = True, masa = 1.0) : self.serijska = serijskaStev self.masa = 1.0 self.spremeniTezo(masa)# uporabimo metodo za sprem. # začetna teža je torej lahko le med 0.85 in 1.15 self.spol = spol
Celotni razred Zajec - 2 defpovejTezo(self) : # težo bomo povedali le na 0.5 kg natančno # z malce drugačnim zaokroževanjem tezaKg = int(self.masa) decim = int((self.masa–tezaKg) * 10) if (decim < 3) : returntezaKg + 0.0 if (decim < 8) : returntezaKg + 0.5 returntezaKg + 1.0 defspremeniTezo(self, novaTeza) : # smislena nova teza je le med 0 in 10 kg # in če ni več kot 15% spremembe od zadnjič spM = self.masa * 0.85 zgM = self.masa * 1.15 if 0 < novaTeza <= 10 andspM < novaTeza <= zgM: self.masa = novaTeza returnTrue # sprememba uspela # v nasprotnem primeru NE spremenimo teže # in javimo, da spremembe nismo naredili returnFalse
Celotni razred Zajec - 3 defpovejSerijsko(self) : returnself.serijska defspremeniSerijsko(self, s = "NEDLOČENO") :self.serijska = s defjeSamec(self) : returnself.spol # ker se spol naknadno NE spremeni, metode za # spreminjanje spola sploh ne ponudimo uporabniku!
Uporaba razreda Zajec z1 = MojaKnj.Zajec("1238-12-0", false, 0.92) ifz1.spremeniTezo(z1.povejTezo() + 0.3) : print"Teža je spremenjena na " + z1.povejTezo()) else : print("Teža je nespremenjena!" + " Prirastek je prevelik! Preveri!") print("Zajec ima ser. št.:" + z1.povejSerijsko()) Zajec z1 = MojaKnj.Zajec() z1.serijska = '1238-12-0' z1.spol = False z1.masa = 0.92 z1.masa = z1.masa + 0.3 print("Zajec ima ser. št.:" + z1.serijska)
Ostale metode • Poleg get/set metod in konstruktorjev • Metode • Odzivi objektov • "znanje objektov" • Objekti tipa list • Se znajo obrniti • seznam.reverse() • Znajo vrniti svoj n-ti element in ga odstraniti • seznam.pop(n) • "naši" razredi • Sprogramiramo znanje – ustrezne metode • Zajec bo znal povedati svojo vrednost, če mu povemo ceno za kg žive teže
Razred Zajec – dodatne metode def vrednost(self, cenaZaKg) : # pove vrednost zajca # zajce tehtamo na dogovorjeno natančnost return cenaZaKg * self.povejTezo() def meNapojiti() : # ugotovimo, če ga je smiselno # napojiti, da bomo "ujeli" naslednjih pol kg # dejanska teža je večja od "izmerjene" return (self.masa – self.povejTezo() > 0)