CATEGORII DOCUMENTE |
Prin folosirea tipurilor abstracte de date, se creaza un tot unitar pentru gestionarea datelor si a operatiilor referitoare la aceste date. Cu ajutorul tipului abstract clasa se realizeaza si protectia datelor, deci elementele protejate nu pot fi accesate numai de functiile membru ale clasei respective. Aceasta proprietate a obiectelor se numeste incapsulare (encapsulation).
In viata de zi cu zi insa ne intilnim nu numai cu obiecte separate, dar si cu diferite legaturi intre aceste obiecte, respectiv intre clasele din care obiectele fac parte. Astfel se formeaza o ierarhie de clase. Rezulta a doua proprietate a obiectelor: mostenirea (inheritance). Acest lucru inseamna ca se mostenesc toate datele si functiile membru ale clasei de baza de catre clasa derivata, dar se pot adauga elemente noi (date membru si functii membru) in clasa derivata. In cazul in care o clasa derivata are mai multe clase de baza se vorbeste despre mostenire multipla.
O alta proprietate importanta a obiectelor care apartin clasei derivate este ca functiile membru mostenite pot fi supraincarcate. Acest lucru inseamna ca o operatie referitoare la obiectele care apartin ierarhiei are un singur identificator, dar functiile care descriu aceasta operatie pot fi diferite. Deci numele functiei si lista parametrilor formali este aceeasi in clasa de baza si in clasa derivata, dar descrierea functiilor difera intre ele. Astfel in clasa derivata functiile membru pot fi specifice referitoare la clasa respectiva, desi operatia se identifica prin acelasi nume. Aceasta proprietate se numeste polimorfism.
Notiunea de polimorfism ne conduce in mod firesc la problematica determinarii functiei membru care se va apela in cazul unui obiect concret. Sa consideram urmatorul exemplu. Declaram clasa de baza baza, si o clasa derivata din acesta clasa de baza, clasa derivata. Clasa de baza are doua functii membru: functia_1 si functia_2. In interiorul functiei membru functia_1 se apeleaza functia_2. In clasa derivata se supraincarca functia membru functia_1, dar functia membru functia_2 nu se supraincarca. In programul principal se declara un obiect al clasei derivate si se apeleaza functia membru functia_2 mostenita de la clasa de baza. In limbajul C++ acest exemplu se scrie in urmatoarea forma. Fisierul virtual1.cpp:
#include <iostream.h>
#include <conio.h>
class baza ;
class derivata : public baza ;
void baza::functia_1()
void baza::functia_2()
void derivata::functia_1()
int main()
Prin executie se obtine urmatorul rezultat:
S-a apelat functia membru functia_2 a clasei de baza
S-a apelat functia membru functia_1 a clasei de baza
Insa acest lucru nu este rezultatul dorit, deoarece in cadrul functiei main s-a apelat functia membru functia_2 mostenita de la clasa de baza, dar functia membru functia_1 apelata de functia_2 s-a determinat inca in faza de compilare. In consecinta, desi functia membru functia_1 s-a supraincarcat in clasa derivata nu s-a apelat functia supraincarcata ci functia membru a clasei de baza. De fapt si din rezultatul executiei programului se obtine acelasi lucru.
Acest neajuns se poate inlatura cu ajutorul introducerii notiunii de functie membru virtuala. Daca functia membru este virtuala, atunci la orice apelare a ei, determinarea functiei membru corespunzatoare a ierarhiei de clase nu se va face la compilare ci la executie, in functie de natura obiectului pentru care s-a facut apelarea. Aceasta proprietate se numeste legare dinamica, iar daca determinarea functiei membru se face la compilare, atunci se vorbeste de legare statica.
Politica de confidentialitate | Termeni si conditii de utilizare |
Vizualizari: 753
Importanta:
Termeni si conditii de utilizare | Contact
© SCRIGROUP 2024 . All rights reserved