Încapsularea presupune și ascunderea datelor sensibile ale unui obiect. Acest lucru este necesar din cel puțin două motive:
- datele membre ale obiectului trebuie să fie consistente. De exemplu:
- varsta unei persoane poate fi cel puțin
0
, într-un interval cunoscut – nu putem avea157
sau1204578
de ani! - numitorul unei fracții trebuie să fie strict pozitiv, iar fracția trebuie să fie ireductibilă.
- varsta unei persoane poate fi cel puțin
- obiectul este o cutie neagră. Utilizatorii săi nu-i cunosc structura internă, ci doar metodele publice prin care poate fi manipulat!
Astfel, datele membru ale unui clase sunt declarate private. Acest lucru duce la respectarea regulilor de mai sus, dar conduce totodată și la imposibilitatea de a vedea din afara clasei care este valoare unei date membru private sau de a o schimba. Aceste operații pot fi făcute prin intermediul metodelor GET și SET (getter-e și setter-e).
Definiții
O metodă GET este o metodă publică a clasei care returnează valoarea ueni date membru private.
O metodă SET este o metodă publică a clasei care atribuie unei date membru private o anumită valoare.
Observații
- getter-ele și setter-erele sunt metode publice;
- ele nu există de la sine, trebuie implementate;
- setter-ele trebuie să valideze valoarea pe care o atribuie datei private și totodată să realizeze anumite prelucrări asupra obiectului, dacă sunt necesare;
- nu există reguli stricte privind numele metodelor GET și SET. O convenție frecventă este următoarea:
- numele metodei lor să fie similar cu cel al datei private pe care o citește/scrie, de regulă scris cu majusculă:
- metoda GET nu are parametri și returnează valoarea datei private corespunzătoare;
- metoda SET are ca parametru noua valoare, iar rezultatul este
void
sau este obiectul curent, pentru a putea înlănțui apelul metodelor.
Exemplu
În exemplul de mai jos implementăm clasa Fractie
, înzestrând-o cu metode GET și SET. Folosim aceste metode la scrierea unei funcții care determină suma a două fracții.
#include <iostream> using namespace std; class Fractie{ private: int numarator, numitor; // proprietăți void Simplifica(); // metodă privată public: Fractie(int _numarator = 0, int _numitor = 1); // constructor Fractie(const Fractie &); // constructor de copiere Fractie & Citeste(); // metodă publică Fractie & Scrie(); // metodă publică // metode GET int Numarator(); int Numitor(); // metode SET Fractie & Numarator(int); Fractie & Numitor(int); }; Fractie::Fractie(const Fractie & F) { // constructor de copiere numarator = F.numarator; numitor = F.numitor; Simplifica(); } Fractie::Fractie(int _numarator /* = 0 */, int _numitor /* = 1 */) { // constructor numitor = _numitor, numarator = _numarator; Simplifica(); } int Fractie::Numarator() { //metoda GET return numarator; } int Fractie::Numitor() { //metoda GET return numitor; } Fractie & Fractie::Numarator(int x) { numarator = x; Simplifica(); return * this; } Fractie & Fractie::Numitor(int x) { // validam valoarea lui x if(x == 0) { cerr << "Numitor nul" << endl; return * this; } numitor = x; if(x < 0) numarator *= -1, numitor *= -1; Simplifica(); return * this; } Fractie & Fractie::Citeste() { // citeste numaratorul si numitorul obiectului curent // returnează obiectul curent int a , b; cin >> a >> b; // validam valorile citite if(b == 0) { cerr << "Numitor nul"<<endl; return * this; } if(b < 0) a = -a , b = -b; numarator = a, numitor = b; Simplifica(); return * this; } Fractie & Fractie::Scrie() { // afisează numaratorul si numitorul obiectului curent // returnează obiectul curent cout << numarator << " " << numitor <<endl; return * this; } void Fractie::Simplifica() { //metoda privata; realizeaza simplificarea fractiei merorate în obiectul curent int a = abs(numarator), b = abs(numitor); while(b) { int r = a % b; a = b; b = r; } numarator /= a; numitor /= a; } Fractie Suma(Fractie F, Fractie G) { // funcție oarecare. Accesam datele private ale obiectelor prin metodele GET si SET int x = F.Numarator() * G.Numitor() + F.Numitor() * G.Numarator(), y = F.Numitor() * G.Numitor(); Fractie R; R.Numarator(x).Numitor(y); // apelam metodele SET return R; // s-a apelat costructorul de copiere } int main() { Fractie a , b; a.Citeste(), b.Citeste(); Suma(a , b).Scrie(); return 0; }