FACULTATEA CALCULATOARE INFORMATIC I MICROELECTRONIC CATEDRA INFORMATICA APLICATA
La Programarea Avansat
A verificat: dr., conf., univ. Kulev Mihail
Chisinau 2014
Tema: Motenirea i compoziia Scopul lucrrii: studierea motenirii, avantajele i dezavantajele studierea compoziiei studierea regulilor de definire a motenirii i compoziiei studierea formelor de motenire studierea iniializatorilor principiul de substituie motenire i compoziie
Sarcina : S se creeze o ierarhie a claselor om i colaborator, care ocup un post anumit i primete un salariu anumit. S se suprancarce operatorii pentru ieiri i intrri de obiecte, constructorul de copiere, operatorii de atribuire utiliznd funciile respective ale clasei de baz
Noiuni de baz Derivarea permite definirea ntr-un mod simplu, eficient i flexibil a unor clase noi prin adugarea unor funcionaliti claselor deja existente, fr s fie necesar reprogramarea sau recompilarea acestora. Clasele derivate exprim relaii ierarhice ntre conceptele pe care acestea le reprezint i asigur o interfa comun pentru mai multe clase diferite. Motenirea poate fi abordat din dou puncte de vedere: al elaboratorului i al utilizatorului clasei. Din punctul de vedere al elaboratorului, motenirea abordeaz comportarea i proprietile clasei derivate ca extensie a proprietilor clasei de baz. Din punct de vedere al utilizatorului motenirea semnific existena unui ir de clase parial intershimbabile cu o interfa unic. (Inginerii TI i inginerii mecanici sunt ambii, n primul rnd, ingineri).
Avantajele motenirii: - micorarea volumului de cod i utilizarea lui repetat, - micorarea numrului de erori i a preului de cost, - interfa unic i substituire, - mrirea vitezei de elaborare. Un neajuns al motenirii ar fi o oarecare micorare a vitezei de executare a codului. Totui eficiena nu trebuie s contrazic avantajele, deoarece cheltuielile reale nu sunt eseniale, ele fiind evitate parial prin utilizarea funciilor. Definirea i utilizarea motenirii :O clas care asigur proprieti comune mai multor clase se definete ca o clas de baz. O clas derivat motenete de la una sau mai multe clase de baz toate caracteristicile acestora, crora le adaug alte caracteristici noi, specifice ei. n general, derivarea unei clase se specific n felul urmtor: class nume_derivata : specificator_acces nume_baza { // corpul clasei }; Specificatorul de acces poate fi unul din cuvintele-cheie: public, private, protected. De exemplu: class Animal{ int NofLegs; public: void Say(){ cout<<!!!; } }; class Dog: public Animal{ // motenire ... }; void main(){ Dog d; d.Say(); } Din exemplu se vede c, funcia i variabila definite n clasa Animal sunt importate i pot fi utilizate de obiectul clasei Dog. Clasa derivat poate s supradefineasc comportarea definit n clasa de baz. (Struul i pinguinul nu zboar, dei sunt psri, dar ornitoringul depune ou, dei este mamifer). Principiul de substituie Motenirea mai presupune c, obiectul clasei derivate poate fi utilizat n locul obiectului clasei de baz: void main(){ Animal *ptr = new Dog;} n exemplul dat se declar un pointer spre clasa de baz deci se ateapt utilizarea obiectului clasei de baz, ns, pointerului i se atribuie obiectul clasei derivate.
Formele motenirii n C++ exist cinci forme diferite de motenire. n lucrarea de fa vor fi analizate trei tipuri, numite moteniri simple care au protecia: - public, - private, - protected, Formele diferite de motenire se utilizeaz pentru modificarea statutului de acces pentru elementele membru ale clasei. Cnd o clas este derivat dintr-o clas de baz, clasa derivat motenete toi membrii clasei de baz (cu excepia unora: constructori, destructor i funcia operator de asignare). Tipul de acces din clasa derivat la membrii clasei de baz este dat de specificatorul de acces. Dac nu este indicat, specificatorul de acces este implicit private. Cnd specificatorul de acces este public, toi membrii de tip public ai clasei de baz devin membri de tip public ai clasei derivate; toi membrii protected ai clasei de baz devin membri protected ai clasei derivate. Membrii private ai clasei de baz rmn private n clasa de baz i nu sunt accesibili membrilor clasei derivate. Aceast restricie de acces ar putea pare surprinztoare, dar, dac s-ar permite accesul dintr-o clas derivat la membrii private ai clasei de baz, noiunile de ncapsulare i ascundere a datelor nu ar mai avea nici o semnificaie. La utilizarea motenirii de tip private a clasei de baz, toate elementele accesibile ( public i protected) din clasa de baz devin private n clasa derivat. Iar la o motenire de tip protected devin protected. Elementele cu acces private ale clasei de baz la orice form de motenire sunt inaccesibile n clasa derivat. nafar de aceasta, formele de motenire se deosebesc prin faptul c motenirea de tip public creaz un subtip de date, adic corespunde principiului de substituie, iar motenirea de tip protected i private nu. Compoziia Compoziia reprezint nc un mecanism legat de POO, care desemneaz relaia dintre obiecte, pe cnd motenirea este relaia dintre clase. Motenirea realizeaz relaia este "is a". Cinele este mamifer, iar mamiferul animal. Compoziia realizeaz relaia conine, are "has a". Automobilul conine motor i roi. Definirea compoziiei De fapt compoziia se aplic foarte larg, deoarece i variabilele predefinite au tip i se utilizeaz la definirea clasei. n cazul claselor utilizator, complexitatea const n utilizarea constructorilor, definirea propriu-zis fiind simpl: class Car{ Engine e; };
Listele de iniializare Se tie c variabilele clasei de baz protejate cu modificatorul private nu sunt accesibile, prin urmare, ele nu pot fi iniializate n constructorul clasei derivate, mai mult ca att, aceasta contrazice principiul de reutilizare a codului. Soluia este una apelul constructorului clasei de baz. Acest lucru are loc dar numai pentru constructorii implicii i de copiere, generai de compilator. Restul constructorilor trebuie s se apeleze manual. Aceeai problem apare i n cazul compoziiei, de asemenea poate fi utilizat numai constructorul implicit i de copiere. Pentru soluionarea acestor probleme sunt utilizate listele de iniializare care permit apelarea oricrui tip de constructor i efectueaz orice iniializare. class Engine{ int power; public: Engine(int p){power=p;} }; class Transport{ ... public: Transport(char*); }; class Car:public Transport{ // Engine e; // public: Car():Transport(automobile),e(10){} };
Pentru apelul constructorului clasei de baz, dup parantezele constructorului clasei derivate prin dou puncte se scrie constructorul clasei de baz, fiind posibil transferul parametrilor din constructorul clasei derivate n constructorul clasei de baz. n cazul compoziiei situaia este asemntoare dar se scrie numele variabilei i nu a constructorului.
Sarcina :S se creeze o ierarhie a claselor om i colaborator, care ocup un post anumit i primete un salariu anumit. S se suprancarce operatorii pentru ieiri i intrri de obiecte, constructorul de copiere, operatorii de atribuire utiliznd funciile respective ale clasei de baz.
Listingul programului : #include<iostream.h> #include<conio.h> #include<iomanip.h> #define an 2013 class om{ protected: char nume[15],prenume[15]; int anul; void citire(); public: void afisare(); int virsta();}; class student:public om{ protected: char grupa[10]; float media; public: void cit_student(); void afis_student(); float bursa();}; class colaborator :public om{ protected: int nr_ore; float plata; public: float salariu(); void cit(); void afis(); }; class ang_calificat:public colaborator{ protected: int an_ang,cat; public: void citire_ang(); void afis_ang(); float salariu_calificat(); int stagiu();}; class student1:public student{ public: float burs();}; float student1::burs(){ float t,r; t=student::bursa(); r=t+200; return r;} void ang_calificat::citire_ang(){ colaborator:cit(); cout<<endl;cout<<"Anul Angajarii = ";cin>>an_ang; cout<<endl;cout<<"Categoria= ";cin>>cat;} int ang_calificat::stagiu(){ return an-an_ang; } float ang_calificat::salariu_calificat(){ float t,u; t=colaborator::salariu(); if(stagiu()<5){u=t*0.1; }else{ if(stagiu()>=5&&stagiu()<=10)u=t*0.15; else u=t*0.2;} if(cat==1)return t+u+(t*0.3); if(cat==2)return t+u+(t*0.4); if(cat==3)return t+u+(t*0.5); else return u; } void ang_calificat::afis_ang(){ colaborator:afis(); cout<<endl<<"Salariu Unui Colaborator calificat cu un staj de Munca de "<<stagiu()<<" Ani , De categoria "<<cat; cout<<endl<<" Este de: "<<salariu_calificat()<<endl; } void colaborator::cit(){ om:citire(); cout<<endl;cout<<"Numarul de Ore = ";cin>>nr_ore; cout<<endl;cout<<"Plata= ";cin>>plata;} void colaborator ::afis(){ om:afisare(); cout<<setw(10)<<nr_ore; cout<<setw(8)<<plata<<endl; } float colaborator::salariu(){ return nr_ore*plata*24;}
void om::citire(){ cout<<" Nume= ";cin>>nume;cout<<endl; cout<<" Prenume= ";cin>>prenume;cout<<endl; cout<<" Anul= ";cin>>anul;cout<<endl; } void om::afisare(){ cout<<setw(10)<<nume; cout<<setw(15)<<prenume; cout<<setw(6)<<anul; } int om::virsta(){ return an-anul;} void student :: afis_student(){ om:afisare(); cout<<setw(10)<<grupa; cout<<setw(8)<<media; } void student::cit_student(){ om :citire(); cout<<endl;cout<<"Grupa= ";cin>>grupa; cout<<endl;cout<<"Media= ";cin>>media;} float student::bursa(){ if(media>8){return 500; }else{ if(media<=8) return 0;}} main(){ student t; student1 t1; colaborator t3; ang_calificat t4; t.cit_student(); t.afis_student(); cout<<endl;cout<<"Virsta= "<<t.virsta()<<endl; cout<<"Bursa Initiala= "<<t.bursa()<<endl; cout<<"Bursa Initiala + 200 Lei = "<<t1.burs()<<endl; t3.cit(); t3.afis(); cout<<"Om Ca simpu Colaborator Are salariu pe Luna De : "<<t3.salariu()<<" Lei "<<endl; t4.citire_ang(); t4.afis_ang();
getch();}
Concluzie :
n urma efecturii acestei lucrri de laborator am nsuit metodele de motenire i compoziia lor. Am observat avantajele i dezavantajele mostenirei, de asemenea am studiat compoziia sa. Un alt principiu a fost studierea regulilor de definire a motenirii i compoziiei si studierea formelor de motenire. Att derivarea ct i compoziia reprezint instrumente de reutilizarea a codului, apare o ntrebare evident: cnd se utilizeaz motenirea i cnd compoziia. n acest sens, exist multe recomandri diferite, ns cel mai simplu este s ne conducem de regula: se pune ntrebarea: clasa nou este un subtip (Dog is an Animal), dac rspunsul este afirmativ, se utilizeaz motenirea, n alt caz se pune ntrebarea: clasa nou reprezint oare un container (Car has a door) n acest caz se utilizeaz compoziia. Exist ns situaii cnd nici aceast strategie nu este suficient. De exemplu, clasa mulime poate fi creat n baza clasei list, dar nu se tie ce mecanism trebuie de folosit. Regulile n acest caz sunt mai complicate, se pune un set de ntrebri: - vor putea fi nlocuite obiectele clasei existente prin obiectele clasei noi? - este necesar s se supradefineasc careva funcie virtual? - prelucreaz oare tipul nou aceleai mesaje ca i cel vechi? - este oare clasa de baz abstract? Dac rspunsurile sunt afirmative, se utilizeaz motenirea