Sunteți pe pagina 1din 5

Tipuri de polimorfism (I)

Polimorfismul.
Funcii Virtuale.
Clase Abstracte

Mihai Gabroveanu

Polimorfismul parametric mecanismul prin


care putem defini o metod cu acelai nume
n aceai clas, funcii care trebuie s difere
prin numrul i/sau tipul parametrilor. Selecia
funciei se realizeaz la compilate (legarea
timpurie (early binging)).

Plimorfismul. Funcii Virtuale

Ce este polimorfismul?

Tipuri de polimorfism (II)

Polimorfismul este capacitatea unor entiti


de a lua forme diferite.
n Etimologia polimorm Poly = multe + Morfm =
forma
n Este unul din conceptele eseniale din POO

Polimorfismul de motenire mecanismul prin


care o metod din clasa de baz este
redefinit cu aceiai parametri n clasele
derivate. Selecia funciei se va realiza la
rulare (legarea ntrziat (late binding,
dynamic binding, runtime binding)).
n n limbajul C++ este implementat cu ajutorul
funciilor virtuale

Plimorfismul. Funcii Virtuale

Plimorfismul. Funcii Virtuale

Upcasting Conversia Tipurilor


n
n

Exemplu (cont.)
class Animal {
protected:
char nume[100];
public:
Animal(char *nume){
strcpy(this->nume,nume);
}
char* sunet(){
return "nu stiu";
}
char* getNume(){
return nume;
}
};

Upcasting = conversia obiectelor claselor derivate ctre obiecte ale


claselor de baz
Considerm urmtoarea ierahie de clase:
class B;
class D: public B{
};

atunci:
B b, *pb; D d,*pd;

Upcasing

b = d;

pb=pd;
d=b
pd=pb;

class Pisica : public Animal{


public:
Pisica(char* nume):Animal(nume) {}
char* sunet() {
return "Miau!";
}
};
class Caine : public Animal{
public:
Caine(char* nume):Animal(nume) {}
char* sunet(){
return "Ham!";
}
};

Downcasting
(incorect)

Plimorfismul. Funcii Virtuale

Exemplu

Plimorfismul. Funcii Virtuale

Exemplu (cont.)
int main(){
Animal *a = new Animal("Jerry");
Pisica *t = new Pisica("Tom");
Caine *c = Caine("Azorel");

Animal
#nume:char [100]

cout << a->getNume()


cout << t->getNume()
cout << c->getNume()
a=t;
cout << a->getNume()
c=a;//incorect
c=t;//incorect

+Animal(nume:char *)
+sunet():char *
+getNume():char *

<< ": " << a->sunet() << endl;


<< ": " << t->sunet() << endl;
<< ": " << c->sunet() << endl;
<< ": " << a->sunet() << endl;

}
OUTPUT:
Jerry : nu stiu
Tom : Miau!
Azorel : Ham!
Azorel : nu stiu! ???

Pisica

Caine
+Caine(name:char *)

+Pisica(name:char *)

+sunet():char *

+sunet():char *

Plimorfismul. Funcii Virtuale

Plimorfismul. Funcii Virtuale

Funcii virtuale
n

Exemplu
sunet() devine
class Animal {
protected:
char nume[100];
public:
Animal(char *nume);
virtual char* sunet();
char* getNume();
};

O funcie virtual este o funcie membr a unei


clase care poate fi nlocuit, n momentul execuiei
programului, cu o funcie membru din clasa derivat.
Sintax declarrii:

void main(){
Animal* animale[] = {
new Pisica("Felix"),
new Caine("Azorel"),
new Pisica("Tom")
};

class IdClasaBaza{
virtual tip idMetodaV(lista_parametri);
};
class IdClasaDerivata : IdClasaBaza{
tip idMetodaV(lista_parametri);
};

Plimorfismul. Funcii Virtuale

Apelul funciilor virtuale


n

Output:
Felix: Miau!
Azorel: Ham!
Tom: Miau!

Plimorfismul. Funcii Virtuale

11

Putem trata colecii de obiecte ale aceleiai


ierarhi ntr-o manier unitar deoarece funcia
apelat virtual este identificat la rulare cu
funcia membr din clasa creia i aparine
obiectul
n Putem asigura independena implementrilor

IdClasaBaza *p = &d;

//va apela metoda definit n clasa IdClasaDerivata.

IdClasaBaza b=d;

//va apela metoda definit n clasa IdClasaBaza

Plimorfismul. Funcii Virtuale

IdClasaDerivata d;

b.idMetodaV();

for(int i = 0; i < 3; i++) {


cout<<animale[i]->getNume()<< ":";
cout<<animale[i]->sunet()<< endl;
}

Avantaje

Cuvntul cheie virtual permite implementarea legturilor dinamice la


apelul funciei prin intermediul unui pointer al clasei de baz. Mai exact,
dac un pointer al clasei de baz indic ctre un obiect din ierahie atunci
se selecteaz la rulare versiunea de funcie corespunztoare tipului de
obiect referit.
De exemplu:
p->idMetodaV();

virtual

10

Plimorfismul. Funcii Virtuale

12

Constructori i Destructori

Funcii virtuale pure

Constructori nu pot fi funcii virtuale.


n Destructori pot fi funcii virtuale. Uneori chiar
este necesar acest lucru.

Funcii virtuale pure sunt funcii virtuale ce


sunt doar declarate n clasa de baz, urmnd
ca acestea sa fie definite n clasele derivate.
n Sintaxa:

class IdClasaBaza{
virtual tip idMetodaVirtPura(lista_parametri) = 0;
};

Plimorfismul. Funcii Virtuale

13

Exemplu

15

Clase Abstracte

class Persoana {
protected:
char *nume;
public:
Persoana(char *nume="") {
this->nume = new char[strlen(nume)+1];
strcpy(this->nume, nume);
}
virtual ~Persoana() {
if (nume){
delete []nume;
nume = 0;
}
cout << "Distruge obiectul de Persoana " <<
endl;
}
};
class Angajat : public Persoana {
char * functia;
public:

Plimorfismul. Funcii Virtuale

Angajat(char *nume="", char * functia):


Persoana(nume) {
this->functia = new char[strlen(functia)+1];
strcpy(this->functia, functia);
}
~Angajat() {
if (functia){
delete []functia;
functia = 0;
}
cout << "Distruge obiectul Angajat " << endl;
}
};
int main() {
Persoana* p = new Angajat("Mircea","Sudor");
delete p; // Apeleaz destructor-ii ~Persona()
si ~Angajat()
return 0;
}

O clas abstract este o clas care conine


cel puin o funcie virtual pur.
n Nu putem crea instane ale claselor abstracte
n Puntem nsa declara pointeri
n Dac o clas motenete o clas abstract i
nu implementeaz toate metodele virtuale
pure atunci ea devine clas abstract.
n

Ce se ntmpl dac destructorul clasei persoana nu este virtual?


Plimorfismul. Funcii Virtuale

14

Plimorfismul. Funcii Virtuale

16

Exemplu (cont.)

Exemplu
FiguraGeometrica
+getPerimetrul():float

class Dreptunghi: public FiguraGeometrica {


Punct colt_s_s; //colt stanga sus
Punct colt_d_j; //colt dreapta jos
public:
Dreptunghi (Punct c_s_s, Punct c_d_j);
float getPerimetrul();
void print();
};

+print():void

Dreptunghi

Dreptunghi::Dreptunghi(Punct c_s_s, Punct


c_d_j): colt_s_s(c_s_s), colt_d_j(c_d_j){
}
float Dreptunghi::getPerimetrul() {
return 2*(colt_d_j.getX()colt_s_s.getX())+2*(colt_s_s.getY()colt_d_j.getY());
}

Cerc

-colt_s_s:Punct

-centru:Punct

-colt_d_j:Punct

-raza:float

+Dreptunghi(c_s_s:Punct,c_d_j:Punct)
+Cerc(c:Punct,r:float)
+getPerimetrul():float

+getPerimetrul():float

+print():void

+print():void

17

Plimorfismul. Funcii Virtuale

Exemplu (cont.)
Clasa abstracta

void Dreptunghi::print(){
cout<<"Dreptunghi
["<<colt_s_s<<","<<colt_d_j<<"]"<<endl;;
}
void main(){
FiguraGeometrica *f[]={new Cerc(Punct(0,0),1),
new Dreptunghi(Punct(0,1),Punct(2,0))};
for(int i=0;i<2;i++){
f[i]->print();
cout<<"Perimetrul="<<f[i]->
getPerimetrul()<<endl;
}
}

Plimorfismul. Funcii Virtuale

19

Tem

Metoda virtuala pur

Metoda e redefinit

(nu are definiie)


class FiguraGeometrica {
public:
virtual float getPerimetrul() = 0;
virtual void print();
};
void FiguraGeometrica::print(){
cout<<"Figura Geometrica Oarecare"<<endl;
}
class Cerc: public FiguraGeometrica {
Punct centru;
float raza;
public:

};
Cerc::Cerc(Punct c, float r):centru(c),
raza(r){
}
float Cerc::getPerimetrul() {
return 2*M_PI*raza;
}
void Cerc::print(){
cout<<"Cerc ("<<centru<<","<<raza<<")"<<endl;
}

Plimorfismul. Funcii Virtuale

Implementati urmtoarea ierahie de clase:


Animal, Mamifer, AnimalZburator, Liliac.
n Imlementai o ierarhie de clase care reprezint
articolele dintr-o bibliotec.
n

Cerc (Punct c, float r);


float getPerimetrul();
void print();

18

Plimorfismul. Funcii Virtuale

20