Etichete: POO

Î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 avea 157 sau 1204578 de ani!
    • numitorul unei fracții trebuie să fie strict pozitiv, iar fracția trebuie să fie ireductibilă.
  • 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;
}