Î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 avea157sau1204578de 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
voidsau 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;
}