410 likes | 582 Views
Nasle đivanje - inheritance. Pojam nasleđivanja u OOP je sličan uobičajenom značenju Nasleđivanje definiše odnos “is a” ili “is a kind of” u prevodu “je” ili “je vrsta” između klasa u odnosu nasleđivanja
E N D
Nasleđivanje - inheritance • Pojam nasleđivanja u OOP je sličan uobičajenom značenju • Nasleđivanje definiše odnos “is a” ili “is a kind of” u prevodu “je” ili “je vrsta” između klasa u odnosu nasleđivanja • Klasa koja nasleđuje od bazne klase “je vrsta” koja može da se klasifikuje i kao bazna klasa • Bazna klasa odgovara širem pojmu koji obuhvata i klasu koja nasleđuje, ali i druge klase • Klasa Mammal – sisar obuhvata razne druge podklase kao Human – čovek, Horse – konj, Whale – kit, Aardvark – mravojed. Sve navedene klase nasleđuju od klase Mammal koja je bazna klasa u tom slučaju
Bazne – base i izvedene – derived klase • Osnovna sintaksa za definisanje klase koja nasleđuje od bazne klase je: • class DerivedClass : BaseClass { • ... • } • Klasa koja nasleđuje dobija sve javne – public i zaštićene – protected članove bazne klase – metode i podatke • Privatni članovi bazne klase su nedostupni klasama koje nasleđuju od bazne klase • Klasa može da nasledi samo od jedne bazne klase
Ponovno nasleđivanje • Klasa koja nasleđuje može da bude bazna klasa za dalje nasleđivanje, ako nije označena kao sealed klasa, od koje više ne može da se nasleđuje • class DerivedSubClass : DerivedClass { • ... • } • Nasleđivanje ne funkcioniše sa strukturama • Struktura ne može da nasledi od klase ili od druge strukture • Klasa takođe ne može da nasledi od strukture
Primeri nasleđivanja • Klasa Object koja pripada imenskom prostoru System je bazna klasa za sve ostale klase, tj. sve ostale klase eksplicitno nasleđuju od klase Object • Definicija klase: • class Mammal {} • se pri kompajliranju prepisuje kao: • class Mammal : System.Object • { • ... • }
Primeri nasleđivanja • class Mammal • { • public void Breathe() • { • ... • } • public void SuckleYoung() • { • ... • } • ... • }
Primeri nasleđivanja • class Horse : Mammal • { • ... • public void Trot() • { • ... • } • } • class Whale: Mammal • { • ... • public void Swim() • { • ... • } • }
Pozivanje konstruktora bazne klase • Kada se kreira objekat izvedene klase, deo objekta koji je definisan baznom klasom se inicijalizuje konstruktorom bazne klase. Ako iz konstruktora izvedene klase nije eksplicitno pozvan konstruktor bazne klase, podrazumevano se poziva default konstruktor bazne klase • Ako je potrebno pozvati neki drugi konstruktor bazne klase, onda se to eksplicitno navodi u konstruktoru izvedene klase • Sa :base (...) se navodi poziv konstruktora bazne klase iz konstruktora izvedene klase
class Horse : Mammal • { • public Horse(string name) • { • ... • } • ... • } • class Horse : Mammal • { • public Horse(string name) • : base() • { • ... • } • ... • }
Dodeljivanje klasa • Promenljivoj deklarisane klase može se dodeliti objekat te iste klase ili objekat izvedene klase • Sva ostala dodeljivanja objekata objektnim promenljivama su nelegalna • Horse myHorse = new Horse(“Neddy”); • Mammal myMammal = myHorse; // legal, Mammal is the base class of Horse+ • Dodeljivanje je moguće, jer su svi konji sisari • Pri tome postoji ograničenje da se preko pokazivača bazne klase mogu koristiti samo članovi klase koji postoje i u baznoj klasi a ne mogu se koristiti članovi klase koji su specifični za izvedenu klasu
Dodeljivanje klasa • Horse myHorse = new Horse(“Neddy”); • Mammal myMammal = myHorse; • myMammal.Breathe(); // OK - Breathe is part of the Mammal class • myMammal.Trot(); // error - Trot is not part of the Mammal class • Pošto su sve klase izvedene iz klase Object, pokazivaču tipa Object se može dodeliti objekat bilo koje klase, ali uz ograničenje pozivanja članova • Obrnuto, tj. dodeljivanje pokazivaču tipa izvedene klase objekta bazne klase nije uvek moguće
Dodeljivanje klasa • Svi objekti tipa izvedene klase su istovremeno i tipa bazne klase, ali obrnuto ne važi, pa shodno tome: • Mammal myMammal = myMammal(“Mammalia”); • Horse myHorse = myMammal; // error • Ako pokazivač na baznu klasu pokazuje na neki izvedeni tip, onda se taj pokazivač može dodeliti drugom pokazivaču na isti tip izvedene klase • Pri tome je potrebno koristiti type cast ili operator as
Dodeljivanje klasa • Horse myHorse = new Horse(“Neddy”); • Mammal myMammal = myHorse; // myMammal refers to a Horse • ... • Horse myHorseAgain = myMammal as Horse; // OK - myMammal was a Horse • ... • Whale myWhale = new Whale(“Moby Dick”); • myMammal = myWhale; • ... • myHorseAgain = myMammal as Horse; // returns null - myMammal was a Whale
Sakrivanje metoda bazne klase • Sakrivanje metoda bazne klase se dešava kada u izvedenoj klasi postoji metod sa istim potpisom – signature, kao i u nekoj baznoj klasi duž putanje nasleđivanja – inheritance path • Onda se pri prevođenju dobija upozorenje za slučaj da se radi o grešci • Ako je sakrivanje ono što se zaista želi, sa new ispred metoda u izvedenoj klasi se naglašava da je to ono što se hoće, i onda se ne dobija upozorenje
Sakrivanje metoda bazne klase • class Mammal • { • ... • public void Talk() // all mammals talk • { • ... • } • } • class Horse : Mammal • { • ... • public void Talk() // horses talk in a different way from other mammals! • { • ... • } • }
Sakrivanje metoda bazne klase - new • class Mammal • { • ... • public void Talk() • { • ... • } • } • class Horse : Mammal • { • ... • new public void Talk() • { • ... • } • }
Virtualni metodi • Virtualni metod u baznoj klasi je predviđen da ima različite implementacije u klasama koje nasleđuju baznu klasu • Primer je metod ToString koji postoji u klasi Object koju nasleđuju sve druge klase • Metod ToString nije adekvatan za izvedene klase, pa ga treba redefinisati u izvedenim klasama, jer osnovna verzija metoda ToString vraca samo naziv klase objekta kao string i ništa više • Metod se označava kao virtuelan sa virtual ispred metoda u baznoj klasi
Virtualni metodi namespace System { class Object { public virtual string ToString() { ... } ... } ... }
Declaring override Methods • Nova implementacija virtuelnog metoda bazne klase koja je adekvatna za izvedenu klasu se obeležava sa override – nadjačati u izvedenoj klasi • class Horse : Mammal • { • ... • public override string ToString() • { • ... • } • }
Declaring override Methods • Iz nove implementacije metoda u izvedenoj klasi se može pozvati metod iz bazne klase sa base • public override string ToString() • { • base.ToString(); • ... • } • Time se može iskoristiti već postojeća implementacija iz bazne klase ako je to potrebno
Ograničenja kod virtuelnih metoda • Private metod bazne klase ne može biti virtuelan • Potpisi – signatures virtuelnog i override metoda moraju biti isti • Pristupi takođe moraju biti isti – oba public ili oba protected • Samo virtual metod bazne klase se može override-ovati, tj. samo ako je dizajner bazne klase to predvideo • Ako metod izvedene klase nije deklarisan sa override, onda samo sakriva – hide metod bazne klase • Override metod izvedene klase je implicitno virtuelan, tj. može se dalje override-ovati u izvedenim klasama od te izvedene klase.
Polimorfizam • Razlika između override-ovanja i sakrivanja metoda postaje očigledna kod polimorfizma • I override kao i hide imaju novu implementaciju metoda u izvedenoj klasi • Ali, polimorfizam postoji samo za override metode • Kada se javlja polimorfizam? • Kada se pokazivaču bazne klase dodeli objekat izvedene klase i onda se preko pokazivača bazne klase zove i izvršava odgovarajući override metod izvedene klase • Ako metod nije override-ovan u izvedenoj klasi, izvršava se metod iz bazne klase – nema polimorfizma • Polimorfizam je vezan za run time – onda se odlučuje koji će se metod zaista pozvati – u zavisnosti od tipa objekta koji je dodeljen pokazivaču bazne klase
Polimorfizam - primer • class Mammal • { • ... • public virtual string GetTypeName() • { • return “This is a mammal”; • } • } • class Horse : Mammal • { • ... • public override string GetTypeName() • { • return “This is a horse”; • } • }
Polimorfizam - primer • class Whale : Mammal • { • ... • public override string GetTypeName () • { • return “This is a whale”; • } • } • class Aardvark : Mammal • { • ... • }
Polimorfizam - primer • Mammal myMammal; • Horse myHorse = new Horse(...); • Whale myWhale = new Whale(...); • Aardvark myAardvark = new Aardvark(...); • myMammal = myHorse; • Console.WriteLine(myMammal.GetTypeName()); // Horse • myMammal = myWhale; • Console.WriteLine(myMammal.GetTypeName()); // Whale • myMammal = myAardvark; • Console.WriteLine(myMammal.GetTypeName()); // Aardvark
protected Access • Public članovi bazne klase su dostupni svim korisnicima objekata te klase, kao i objektima izvedenih klasa • Protected članovi bazne klase su dostupni samo objektima izvedenih klasa, ali ne i korisnicima objekata bazne klase koji nisu objekti izvedene klase • Private članovi bazne klase su dostupni isključivo objektima bazne klase i nikome više • Princip – enkapsulacija, je da što manji broj članova klase ima public i private pristup, samo oni članovi klase za koje je to neophodno
Extension Methods Extension metodi omogućavaju proširivanje tipova - klasa i struktura sa statičkim metodima static class Util { public static int Negate(this int i) { return –i; } } This ispred int u zagradi označava da se radi o extension metodu
Extension Methods • int x = 591; • Console.WriteLine(“x.Negate {0}”, x.Negate()); • int x = 591; • Console.WriteLine(“x.Negate {0}”, Util.Negate(x));