Podklase

Šta ako imamo neke objekte koji sadrže elemente kao i već postojeća klasa (npr. NebeskaTela kod nas), ali imaju dodatne objekte, ili dodatne potrebne metode? U ovakvom slučaju koristimo podklase.

Želimo da napravimo klasu Planete, koja će biti podklasa klase NebeskaTela, koja će već imati određen tip, ali ima i oko koje zvezde se okreće, i dodatno, ima metodu koja nam govori drugačiji citat.

  
class Planete(NebeskaTela):
    tip="planeta"
    def __init__(self,precnik,otkrivac,zvezda):
        self.precnik=precnik
        self.otkrivac=otkrivac
        self.zvezda=zvezda
    def citat(self):
        return "Jednom kad donesete odluku, citav svemir se udruzi da bi se ostvarila."
            

Do sada nismo obraćali pažnju na to što se u zagradi kod definisanja klasa navodi object. To u stvari znači da klasa koju pravimo nasleđuje klasu čije ime smo naveli u zagradi. Kada navedemo klasu object, to znači da pravimo objekat, i klasa nasleđuje sve što se nalazi u objektu. Ako navedemo ime neke klase koju smo sami napravili, kao u ovom slučaju NebeskaTela, klasa Planete će naslediti sve što se nalazi u klasi NebeskaTela.

Hajde da napravimo dva objekta, jedan iz klase NebeskaTela i jedan iz klase Planete.

  
sunce=NebeskaTela("zvezda",1369000,"svi")
zemlja=Planete(6370,"svi mi","Sunce")
            

Kao što se može primetiti, inicijalizacija, odnosno kreiranje objekta, se razlikuje. Razlikuje se zbog toga što smo u klasi Planete ponovo definisali (redefinisali) funkciju inicijalizacije.
Redefinisanje funkcioniše na sledeći način: sve metode koje su definisane u nadklasi se nalaze i mogu se koristiti u okviru podklase, sem ako se redefinišu, u tom slučaju, pri pozivanju metode koristi se redefinisana metoda.

Pokažimo to na primeru (pretpostavimo da smo napravili klase NebeskaTela i Planete, kao i instance sunce i zemlja):

  
print(sunce.sve())
print(zemlja.sve())
print(sunce.citat())
print(zemlja.citat())
            

Kao rezultat ćemo dobiti:

			Ovo je zvezda, precnika 1369000 i otkrio/otkrili su je svi!
			Ovo je planeta, precnika 6370 i otkrio/otkrili su je svi mi!
			Postoji teorija koja kaze da ce, ukoliko ikada iko bude
					otkrio koja je svrha svemira i zasto on postoji,
					ovaj smesta isceznuti i biti zamenjen necim jos neobicnijim
					i neobjasnjivijim. Postoji i druga teorija koja tvrdi da se sve to vec desilo.
			Jednom kad donesete odluku, citav svemir se udruzi da bi se ostvarila.
        

Kao što se može primetiti, metoda sve, koja nije redefinisana, ispisuje isti oblik, samo sa različitim vrednostima, dok metoda citat, koja je redefinisana, vraća različite citate.

Vežba: Napraviti klasu Zivotinje, sa vrstom i imenom životinje, i njenu podklasu Pas, koja će imati ime životinje, ime vlasnika, i vrstu podrazumevanu za sve, koja ima vrednost “pas”. Zatim napraviti tri instance, dve iz klase Zivotinje sa vrstom “pas” i “macka” i jednu iz klase Pas. Napraviti metodu oglasavanje kao u prethodnoj vežbi. Isprobati oglasavanje na sve tri instance.

Super

Nekada postoji potreba da se metod koji je u nadklasi iskoristi i dopuni. U tom slučaju koristimo super funkciju, na sledeći način:

  
class Planete(NebeskaTela):
    tip="planeta"
    def __init__(self,precnik,otkrivac,zvezda):
        self.precnik=precnik
        self.otkrivac=otkrivac
        self.zvezda=zvezda
    def sve(self):
        stari=super(Planete,self).sve()     #ovo je bitno!
        return stari + " Okrece se oko zvezde " + self.zvezda
zemlja=Planete( 6370,"svi mi","Sunce")
print(zemlja.sve())
            

Napomena: Za pokretanje ovog koda neophodan je i deo sa klasom NebeskaTela i rad u lokalnom Pajtonu (uputstvo možete naći na...)

Kao rezultat pozivanja dobićemo:

			 Ovo je planeta, precnika 6370 i otkrio/otkrili su je svi mi! Okrece se oko zvezde Sunce
			 

super funkcija ima sledeći potpis,
super(odKojeKlaseNadklasa,self).imeMetode(onoStoSeSaljeMetodi)

Ovakav poziv super funkcije će kao svoju povratnu vrednost imati povratnu vrednost one metode koju smo naveli onako kako je definisana u nadklasi klase koju smo naveli. (U našem slučaju, povratnu vrednost metode sve koja je definisana u klasi NebeskaTela)

Vežba: Isprobati ovaj kod i sa instancom sunce=NebeskaTela("zvezda",1369000,"svi"). Pogledati razliku.

Dodatno

U konzolu unesite, a zatim i pokrenite sledeći kod:

  
class NebeskaTela(object):
    galaksija="Mlecni put"
    def __init__(self,tip,precnik,otkrivac):
        self.tip=tip
        self.precnik=precnik
        self.otkrivac=otkrivac
        
sunce=NebeskaTela("zvezda",1369000,"svi")
print(sunce)
            
Kopiraj

Kao što ste primetili, ne dobija se lep prikaz ovog elementa. Da bismo promenili kako će print funkcija da štampa instancu, možemo je redefinisati u okviru klase. To ćemo uraditi na sledeći način:

  
class NebeskaTela(object):
    galaksija="Mlecni put"
    def __init__(self,tip,precnik,otkrivac):
        self.tip=tip
        self.precnik=precnik
        self.otkrivac=otkrivac
    def __repr__(self): #redefinisanje funkcije print (bitno!)
        return "Ovo je %s nebesko telo." % (self.tip)
sunce=NebeskaTela("zvezda",1369000,"svi")
print(sunce)
            
Kopiraj

Nakon pokretanja programa dobijamo:

			 Ovo je zvezda nebesko telo.