370 likes | 580 Vues
Objektno orijentisano programiranje. Naslje đivanje. Nasljeđivanje. Pojam nasljeđivanja Definisanje izvedenih klasa Prava pristupa u izvedenim klasama Pozivanje konstruktora i destruktora Klasni dijagrami. Pojam nasljeđivanja. Jedan on najvažnijih OOP koncepata
E N D
Objektno orijentisano programiranje Nasljeđivanje
Nasljeđivanje • Pojam nasljeđivanja • Definisanje izvedenih klasa • Prava pristupa u izvedenim klasama • Pozivanje konstruktora i destruktora • Klasni dijagrami
Pojam nasljeđivanja • Jedan on najvažnijih OOP koncepata • Omogućava ponovno korištenje koda tako što se koriste postojeće klase za izvođenje novih • Često se sreće slučaj da je jedna klasa objekata (klasa B) podvrsta neke druge klase (klasa A) • Geometrijske figure u ravni su klasa koja je okarakterisana koordinatama težišta. Krug je vrsta figure u ravni koja je okarakterisana dužinom poluprečnika. Kvadrat je vrsta figure u ravni koja je okarakterisana dužinom ivice. • Objekti klase B imaju sve osobine klase A i još neke specijalne, sebi svojstvene osobine • Specijalnija klasa B se izvodi iz generalnije klase A
Pojam nasljeđivanja • Opisuje relaciju “je tipa” ili “je vrste” • Predstavlja odnos između klasa • Nove klase specijaliziraju postojeće klase Musician Generalizacija Osnovna klasa Violin Player Specijalizacija Primjer nasljeđivanja Izvedena klasa
Izvođenje, nasljeđivanje • Klasa B nasljeđuje osobine klase A • Ovakva relacija između klasa naziva senasljeđivanje (engl. inheritance) • Relacija nasljeđivanja se najčešće prikazuje usmjerenim grafom
Figura 2Dfigura 3DFigura Krug Kvadrat Trougao Sfera Kupa Tetraedar Relacije nasljeđivanja specijalizacija generalizacija
Hijerarhije klasa • Klase povezane relacijama nasljeđivanja formiraju hijerarhije klasa Musician plays Musical Instrument String Musician Stringed Instrument plays ??? Violin Player Violin ??? plays
Jednostruko i višestruko nasljeđivanje • Izvođenje iz jedne osnovne klase • Izvođenje iz više osnovnih klasa Stringed Instrument Musical Instrument Pluckable Violin Stringed Instrument
Polimorfizam • Naziv metode definisan u osnovnoj klasi • Implementacija metode definisana u izvedenim klasama String Musician TuneYourInstrument( ) Guitar Player Violin Player TuneYourInstrument( ) TuneYourInstrument( )
Apstraktne osnovne klase • Neke klase se definišu samo da se na osnovu njih kreiraju izvedene klase • Nema smisla kreirati instance ovih klasa • Ove klase se nazivaju apstraktne Stringed Musician { abstract } Guitar Player « concrete » Violin Player « concrete »
Interfejsi • Interfejsi sadrže samo operacije (nazive funkcija bez njihove implementacije) Musician « interface » Ne mogu se kreirati instance interfejsa String Musician { abstract } Mogu sadržati implementacijuNe mogu se kreirati instance apstraktnih klasa Moraju implementirati sve naslijeđene operacije. Mogu se kreirati instance klase Violin Player « concrete »
Terminologija • Ako je klasa B naslijedila klasu A (izvedena iz klase A), kaže se još da je: • klasa A osnovna klasa (engl. base class), a klasa B izvedena klasa (engl. derived class); • klasa A nadklasa (engl. superclass), a klasa B podklasa (engl. subclass); • klasa A roditelj (engl. parent), a klasa B dijete (engl. child).
public osnovna klasa-e : virtual protected private , Definisanje izvedenih klasa • Izvedena klasa se definiše navođenjem sljedeće konstrukcije između identifikatora klase i znaka {
Definisanje izvedenih klasa (C++) classOsnovna {int i; // privatni podatak clan osnovne klase public:void f();// javna funkcija clanica osnovne klase}; classIzvedena : publicOsnovna {int j; // privatni podatak clan izvedene klase public:void g(); // javna funkcija clanica izvedene klase}; void main () { Osnovna b; Izvedena d; b.f(); b.g(); // GRESKA: g je funkcija izvedene klase, a b je objekat osnovne d.f(); // objekat izvedene klase d ima i funkciju f, d.g(); // i funkciju g}
Definisanje izvedenih klasa (C#) • Sintaksa za definisanje nasljeđivanja • Izvedena klasa nasljeđuje većinu elemenata svoje osnovne klase • Pristup naslijeđenim članovima izvedene klase ne može biti višeg nivoa nego u osnovnoj klasi class Token { ... } class CommentToken: Token { ... } Token « concrete » Izvedena Osnovna CommentToken « concrete »
Vidljivost i prava pristupa • Redefinisanje identifikatora iz osnovne klase unutar izvedene klase sakriva identifikator iz osnovne klase. • Pristup sakrivenom članu iz osnovne klase unutar izvedene klase je moguć na način: <osnovna klasa>::<član> (C++). • Izvedena klasa nema pravo pristupa privatnim članovima osnovne klase. • Labela protected: označava dio klase koji je pristupačan kako članicama tako i funkcijama izvedenih klasa. • Članovi u ovoj sekciji se nazivaju zaštićenim članovima (engl. protected members).
Vidljivost i prava pristupa class Osnovna {int p;protected:int z;public:int j;}; class Izvedena : public Osnovna {public:void write(int x) { j=z=x; // moze da pristupi javnom i zasticenom clanu, p=x; // ! GRESKA: privatnom clanu se ne moze pristupiti }}; void f() { Osnovna b; b.z=5; // odavde ne moze da se pristupa zasticenom clanu}
Pristup članovima osnovne klase class Token { ... class Outside protected string name; { } void Fails(Token t) class CommentToken: Token { { ... ... public string Name( ) t.name { ... return name; } } } } • Naslijeđeni zaštićeni (protected) članovi su implicitno zaštićeni i u izvedenoj klasi • Metode izvedene klase mogu pristupiti samo naslijeđenim članovima (protected, public) ili vlastitim novim članovima definisanim u izvedenoj klasi û
Načini izvođenja (C++) • Privatno (podrazumijevano ako se ne navede drugo) – svi naslijeđeni članovi postaju privatni u izvedenoj klasi • Zaštićeno – svi naslijeđeni članovi postaju zaštićeni u izvedenoj klasi • Javno – prava pristupa se ne mijenjaju u odnosu na osnovnu klasu (javni ostaju javni, zaštićeni ostaju zaštićeni)
Tipovi nasljeđivanja (C#) • Nasljeđivanje implementacije (implementation inheritance) • Izvedena klasa nasljeđuje osobine druge klase, atribute i metode, uključujući implementaciju metoda • Nasljeđivanje interfejsa (interface inheritance) • Izvedena klasa nasljeđuje samo potpise metoda iz jednog ili više interfejsa, bez implementacije metoda
Konstruktori i destruktori • Prikreiranju objekta izvedene klase poziva se konstruktor te klase, ali i konstruktor osnovne klase. • U zaglavlju definicije konstruktora izvedene klase, u listi inicijalizatora,moguće je navesti i inicijalizator osnovne klase (argumente poziva konstruktora osnovne klase). • To se radi navođenjem imena osnovne klase i argumenata poziva konstruktora osnovne klase
Konstruktori i destruktori (C++) • class Osnovna {int bi;public: Osnovna(int); // konstruktor osnovne klase};Osnovna::Osnovna (int i) : bi(i) {/*...*/} • class Izvedena : public Osnovna {int di;public: Izvedena(int);}; • Izvedena::Izvedena (int i) : Osnovna(i),di(i+1) {/*...*/}
Poziv konstruktora osnovne klase (C#) • Rezervisanariječbase • A private base class constructor cannot be accessed by a derived class • Use the base keyword to qualify identifier scope class Token { protected Token(string name) { ... } ... } class CommentToken: Token { public CommentToken(string name) : base(name) { } ... }
Redoslijed poziva • Pri kreiranju objekta izvedene klase redoslijed poziva konstruktora je sljedeći: • inicijalizuje se podobjekat osnovne klase, pozivom konstruktora osnovne klase; • inicijalizuju se podaci članovi, eventualno pozivom njihovih konstruktora, po redoslijedu deklarisanja; • izvršava se tijelo konstruktora izvedene klase. • Pri uništavanju objekta, redoslijed poziva destruktora je uvek obratan.
Redoslijed poziva (C++) classElement{public:Klasa() {cout<<"Konstruktor klase Element .\n";} ~Klasa() {cout<<"Destruktor klase Element .\n";}};class Osnovna {public: Osnovna() {cout<<"Konstruktor osnovne klase."<<endl;} ~Osnovna() {cout<<"Destruktor osnovne klase."<<endl;}};class Izvedena : public Osnovna { Element x;public: Izvedena() {cout<<"Konstruktor izvedene klase."<<endl;} ~Izvedena() {cout<<"Destruktor izvedene klase."<<endl;}};void main () { Izvedena d;}/* Izlaz programa:Konstruktor osnovne klase.Konstruktor klase Element.Konstruktor izvedene klase.Destruktor izvedene klase.Destruktor klase Element.Destruktor osnovne klase.*/
Višestruko nasljeđivanje (C++) • Višestruko nasljeđivanje (engl. multiple inheritance) omogućava nasljeđivanje osobina više osnovnih klasa • Klasa se deklariše kao nasljednik više klasa tako što se u zaglavlju deklaracije navode osnovne klase. • Ispred svake osnovne klase treba da stoji riječ public, da bi izvedena klasa nasljeđivala prava pristupa članovima. classIzvedena : publicOsnovna1, publicOsnovna2, privateOsnovna3 {/* ... */};
Konstruktori i destruktori kod višestrukog nasljeđivanja • Sva pravila o nasljeđenim članovima važe i kod višestrukog nasljeđivanja. • Konstruktori osnovnih klasa se pozivaju prije konstruktora članova izvedene klase i konstruktora izvedene klase. • Konstruktori osnovnih klasa se pozivaju po redoslijedu deklarisanja. • Destruktori osnovnih klasa se izvršavaju na kraju, poslije destruktora izvedene klase i destruktora članova.
Višestruki podobjekti classOsnovna { public: int x; };classIzv1 : publicOsnovna {/*...*/};classIzv2 : public Osnovna {/*...*/};classVIzv : publicIzv1, publicIzv2 { public: int fun(); }; Osnovna x Izv1 Izv2 x x VIzv ? X ? X
Višestruki podobjekti • Ako klasa ima višestruku nevirtuelnu osnovnu klasu X onda će objekti te klase imati više podobjekata tipa X • Članovima osnovne klase X može se pristupiti nedvosmislenim navođenjem njihove pripadnosti, korišćenjem operatora : : VIzv :: Izv1 :: Osnovna :: X • Konverzija pokazivača tj reference na izvedenu klasu u pokazivač/referencu na višestruku osnovnu klasu može se izvršiti samo ako je nedvosmislena • Nedvosmislenost znači da ne postoje dva ili više entiteta koja odgovaraju navedenom imenu void VIzv :: fun() { x=2; // dvosmislenost, Izv1::X ili Izv2::X , greška !!! Izv1::x = Izv2::x + 1; // ispravno }
Višestruki podobjekti Osnovna Osnovna Osnovna x x x Izv1 Izv2 Izv1 Izv2 x x x x VIzv VIzv ? X ? X x x Nije dozvoljeno da jedna klasa bude višestruka direktna osnovna klasa! class A : public X, public X { };
Virtuelne osnovne klase • Osnovna klasa može biti virtuelna – treba je deklarisati kao virtuelnu sa virtual • Ako je osnovna klasa virtuelna onda se podobjekti osnovne klase unutar objekta izvedene klase dijele sa svim podobjektima koji imaju istu osnovnu klasu kao virtuelnu • Obraćanje članu osnovne klase nije dvosmisleno ako postoji samo jedan primerak tog člana bez obzira na način pristupa • Ako je potrebno da izvedena klasa posjeduje samo jedan podobjekat indirektne osnovne klase onda osnovnu klasu treba deklarisati kao virtuelnu
Virtuelne osnovne klase B class B {/*...*/};class X : virtual public B {/*...*/};class Y : virtual public B {/*...*/};class Z : public X, public Y {/*...*/}; X Y Z • Klasa Z ima samo jedan skup članova klase B. • Moraju se i X i Y virtuelno izvesti iz B; • Ako je samo jedna izvedena virtuelno ostaju dva skupa članova. • Konstruktori virtuelnih osnovnih klasa se pozivaju prije konstruktora nevirtuelnih osnovnih klasa. • Svi konstruktori osnovnih klasa se pozivaju prije konstruktora članova i konstruktora izvedene klase.
Višestruko nasljeđivanje u C# • Nije podržano nasljeđivanje iz više direktnih osnovnih klasa • Ne postoji mogućnost višestrukog nasljeđivanja za slušaj nasljeđivanja implementacije • Moguće je nasljeđivanje iz više interfejsa • Višestruko nasljeđivanje može se primijeniti samo za slučaj nasljeđivanja interfejsa
Deklaracijainterfejsa • Rezervisana riječ interface Imena interfejsa obično počinju slovom“I” interface IToken { int LineNumber( ); string Name( ); } IToken « interface » LineNumber( ) Name( ) Bez modifikatora pristupa Bez implementacije
Implementacija više interfejsa • Klasa može implementirati više interfejsa (ili nijedan) • Interfejs može naslijediti više drugih interfejsa (ili nijedan) • Prava pristupa u klasi mogu biti višeg nivoa nego u interfejsima • Klasa mora implementirati sve naslijeđene metode interfejsa interface IToken { string Name( ); } interface IVisitable { void Accept(IVisitor v); } class Token: IToken, IVisitable { ... } IToken « interface » IVisitable « interface » Token « concrete »
Implementacija metoda interfejsa • Metoda koja implementira metodu interfejsa mora biti ista kao metoda interfejsa • Implementirajuća metoda može biti virtuelna ili nevirtuelna class Token: IToken, IVisitable { public virtual string Name( ) { ... } public void Accept(IVisitor v) { ... } } Isti nivo pristupa Isti povratni tip Isto ime Isti parametri