oop nasledjivanje
DESCRIPTION
Elektronski fakultetTRANSCRIPT
Objektno-orijentisanoprogramiranje
Nasledjivanje
Nasleđivanje klasa Pri razmatranju skupa objekata, pogodno je
grupisati ih po sličnim atributima i zajedničkim operacijama. Na primer, hoćemo da napravimo klasu koja će predstavljati sve objekte koji služe za transport. Ona bi uključivala objekte aviona, objekte automobila ili čak objekte brodova. Drugim rečima, ona bi objedinjavala klase kopneniTransport, vazdusniTransport i morskiTransport. Nazovimo tu klasu Transport.
Nasleđivanje klasa Klasa Transport je na vrhu hierarhije. Ona se
zove superklasa (roditeljska klasa), dok se klase vazdusniTransport, morskiTransport i kopneniTransport nazivaju podklase.
Atribute klase Transport (npr. maksimalan broj putnika) kao i operacije te klase (transportuj, stani, kreni) su nasledile podklase. Može se takođe reći da su podklase izvedene iz roditeljske klase.
Objekti veoma retko pripadaju totalno različitim grupama – često postoji značajno preklapanje operacija među grupama objekata.
class Transport {
int brzina;int stanje_rezervoara;
protected:void povecajDotokGoriva();void ukljuciSistemKocenja();
public:void ubrzaj();void uspori();
};
Transport.h
Privatni atributi
Implementacioni deo
Interfejs (javni deo) klase
Transport.cppvoid Transport::povecajDotokGoriva(){}void Transport::ukljuciSistemKocenja(){}void Transport::ubrzaj(){
povecajDotokGoriva();}void Transport::uspori(){
ukljuciSistemKocenja();}
Definicija izvedene klase Nasleđivanje se vrši tako što se pri deklaraciji klase, posle
navođenja imena klase stavi znak “:“ (dve tačke), zatim tip nasleđivanja (private, protected ili public) i ime klase iz koje se vrši nasleđivanje:
(VazdusniTransport.h)
class vazdusniTransport : public Transport{
int visina;public:
povecajVisinu();smanjiVisinu();
}
VazdusniTransport.cppvoid vazdusniTransport::povecajVisinu(){
visina += 10;uspori();
}void vazdusniTransport:: smanjiVisinu(){
visina -= 15;ubrzaj();
}
(main.cpp)
void main(){ vazdusniTransport avion; avion.povecajVisinu(); avion.ubrzaj(); // nasledjena operacija}
Polimorfizam Normalno, svaki tip vozila funkcioniše na drugačiji
način – brod, avion i automobil usporavaju na sasvim drugačiji način. To znači da im se menjaju i implementacioni detalji, tj. svaki od njih bi trebalo da ima različite funkcije za povećanje dotoka goriva i sistema kočenja. Sa druge strane, interfejs bi ostao isti – usporavanje i ubrzavanje vozila.
Polimorfizam omogućava da klasa saopšti da ima isti interfejs kao i osnovna klasa, ali da je ponašanje izvedene klase različito od ponašanja osnovne klase.
Polimorfizam omogućava upravo to – da izvedene klase imaju svoje “verzije” operacija deklarisanih u osnovnoj klasi.
Virtualne funkcije Polimorfizam se postiže deklarisanjem
željenih operacija osnovne klase virtualnim. Ako izvedena klasa ne definiše virtualnu funkciju osnovne klase, ona jednostavno usvaja ponašanje osnovne klase.
Virtualna funkcija je funkcija (operacija) članica za koju se očekuje da bude redefinisana u nasleđenim klasama.
Primer: bazna i izvedena klasaclass Base{public: virtual void NameOf(); // Virtual void InvokingClass(); // Nonvirtual};void Base::NameOf(){ cout << "Base::NameOf\n";}
void Base::InvokingClass(){ cout << "Invoked by Base\n";}
class Derived : public Base{public: void NameOf(); void InvokingClass(); };
void Derived::NameOf(){ cout << "Derived::NameOf\n";}
void Derived::InvokingClass(){ cout << "Invoked by Derived\n";}
Primer: glavna f-ja i rezultat int main(){ Derived c; Derived *a = &c; Base *b = &c;
b->NameOf(); // Poziv virtualne f-je b->InvokingClass(); // Poziv ne-virtualne f-je a->NameOf(); // Poziv virtualne f-je a->InvokingClass(); // Poziv ne-virtualne f-je}
(Rezultat)Derived::NameOfInvoked by BaseDerived::NameOfInvoked by Derived
Poziv predefinisane funkcije
Ukoliko je potrebno pozvati predefinisanu funkciju (članicu roditeljske klase), koristi se operator pripadnosti “::”.
U funkcijama izvedene klase predefinisana funkcija f1 se poziva:
<OsnovnaKlasa>::f1()
Transport.h (osnovna klasa)class Transport {
int brzina;int stanje_rezervoara;
public:void povecajDotokGoriva();virtual void ukljuciSistemKocenja() {
cout << “Kocenje inicirano” << endl;}void ubrzaj() {povecajDotokGoriva();}char* uspori() {ukljuciSistemKocenja();}
};
vazdusniTransport.h i main f-jaclass vazdusniTransport : public Transport{public: virtual void ukljuciSistemKocenja(){
Transport::ukljuciSistemKocenja();cout << “Vazdusne kocnice podignute”;
};}
(main.cpp)void main(){ Transport *vozilo; vozilo = new vazdusniTransport; vozilo->koci();}
(Rezultat)Kocenje iniciranoVazdusne kocnice podignute
Kreiranje i brisanje objekata izvedene klase Kada se kreira objekat izvedene klase, najpre se
kreira objekat osnovne klase (za šta se poziva konstruktor osnovne klase), a zatim se kreiraju atributi izvedene klase i izvršava telo konstruktora izvedene klase. Zbog toga prva stavka u delu za inicijalizaciju konstruktora izvedene klase, treba da bude poziv konstruktora osnovne klase. Ukoliko je on izostavljen, automatski se poziva konstruktor bez argumenata.
Kada se briše objekat izvedene klase redosled operacija je obrnut. Poziva se destruktor izvedene klase, a on na kraju implicitno poziva destruktor osnovne klase.
Primer konstruktora i destruktora osnovne i izvedene klaseclass Base{ char* name;public: Base(int size) { name = new char[size]; } virtual ~Base() { delete [] name; }};
class Derived : public Base{ int* vec;public: Derived( int size1, int size2 ) : Base( size1 ) { vec = new int[size2]; } ~Derived() { delete [] vec; } };
Zadatak 5. Na programskom jeziku C++ definisati klasu Krug, pri čemu su
privatni atributi klase koordinate centra i poluprečnik kruga. Ova klase treba da sadrži konstruktor koji postavlja poluprečnik, virtuelnu funkciju za promenu poluprečnika koja poluprečnik postavla na novu zadatu vrednost, virtuelnu funkciju za štampanje poluprečnika na standardni izlaz I inline funkciju koja vraca vrednost poluprečnika.
Definisati klasu ObojeniKrug (javno izvedenu iz klase Krug) koja sadrži zaštićene atribute kojima se kodira boja, konstruktor koji inicijalizuje sve atribute, virtualnu funkciju za promenu poluprečnika koja poluprečnik povećava za zadatu vrednost, i virutuelnu funkciju za stampanje svih atributa na standardni izlaz.
Za krugove čija je boja zelena definisati posebnu klasu ZeleniKrug koja je izvedena iz klase ObojeniKrug. Ova klasa sadrži konstruktor sa potrebnim argumentima i operatorsku funkciju operator+=() za povećanje intenziteta boje.
U glavnom programu konstruisati po jedan objekat svake klase i pozvati sve implementirane funkcije.
Čiste virtualne funkcije Postoje situacije kada je osnovna klasa
jednostavno skelet ili okvir, dok se funkcionalnost dobija tek kod izvedenih klasa, tj. Situacije kaba bi svako pisanje tela funkcije u osnovnoj klasi bilo beskorisno, s obzirom da bi i onako bilo zamenjeno u izvedenoj klasi.
Čista virtualna funkcija je virtualna funkcija kojoj nije potrebno telo. Ona u deklaraciji iza imena sadrži notaciju “=0”.virtual void povecajDotokGoriva()=0;
Apstrakne klase Ukoliko klasa ima bar jednu čistu virtualnu
funkciju, ona se naziva apstraktnom. Apstaktna klasa je klasa koja sadrži čistu
virtualnu funkciju ili klasa koja nasleđuje virtualnu funkciju ali je ne definiše. Ne može da se kreira primerak apstaktne klase, mada može da postoji pokazivač ili referenca na apstaktnu klasu.
Postoje dva razloga da se klasa učini apstaktnom. Prvi je da se izbegne pisanje beskorisnih tela funkcija, a drugi da se korisnici spreče da kreiraju primerke te klase. Kada se kreira familija klasa, a samo izvedene klase treba da budu instancirane, treba u osnovnoj klasi koristiti čiste virtualne funkcije.
Osnovna *pok; //pokazivac na objekat klase Glavnapok = new Osnovna; //nije ispravnopok = new Izvedena; //ispravnovoid uradiNesto(Osnovna & ref); /* funkcija koja uzima
referencu na objekat klase Osnovna */
Zadatak 6Kreirati: Apstraktnu klasu Ntougao koja ima:
zaštićene atribute: broj temena i vektor duzina stranica,
javne funkcije: konstruktor koji inicijalizuje broj temena, funkciju za izracunavanje obima I cistu virtuelnu funkciju za izracunavanje povrsine mnogougla.
Prijatelljsku funkciju >> za ucitavanje duzina stranica iz tekstualnog toka podataka.
Klasu Trougao javno izvedenu iz klase Ntougao koja nije apstraktna.