Ascunderea funcționalității clasei de bază
C++ permite definirea în clasa derivată a unor variabile și funcții cu aceleași nume ca cele din clasa de bază. În acest caz, variabilele și funcțiile din clasa derivată vor ascunde variabilele și funcțiile omonime din clasa de bază.
Ascunderea funcțiilor
O clasă derivată poate defini o funcție cu același nume ca o funcție din clasa de bază, fie cu aceeași listă de parametri, fie cu alta. Pentru compilator, o astfel de funcție va fi tratată ca independentă față de clasa de bază. O astfel de definire nu este o suprascriere (override) a funcției din clasa de bază.
#include <iostream>
class Person
{
public:
Person(std::string name, unsigned age) : name(name), age(age)
{}
void print() const
{
std::cout << "Name: " << name << "\tAge: " << age << std::endl;
}
private:
std::string name;
unsigned age;
};
class Employee: public Person
{
public:
Employee(std::string name, unsigned age, std::string company):
Person(name, age), company(company)
{ }
void print() const
{
std::cout << "Works in " << company << std::endl;
}
private:
std::string company;
};
int main()
{
Employee tom{"Tom", 38, "Google"};
tom.print(); // Works in Google
}
Aici, clasa Person, care reprezintă o persoană, definește funcția print(), care afișează valorile variabilelor name și age.
Clasa Employee, care reprezintă un angajat și este derivată din Person, definește și ea o funcție print(), dar care afișează valoarea variabilei company.
Prin urmare, obiectul Employee va utiliza implementarea funcției print din clasa Employee, nu cea din Person.
Funcția print din Employee ascunde funcția print din Person. Totuși, uneori avem nevoie să apelăm implementarea funcției definite în clasa de bază. În acest caz, putem folosi operatorul :::
baza::funcție
De exemplu:
#include <iostream>
class Person
{
public:
Person(std::string name, unsigned age) : name(name), age(age)
{}
void print() const
{
std::cout << "Name: " << name << "\tAge: " << age << std::endl;
}
private:
std::string name;
unsigned age;
};
class Employee: public Person
{
public:
Employee(std::string name, unsigned age, std::string company):
Person(name, age), company(company)
{ }
void print() const
{
Person::print(); // apelăm funcția print din clasa de bază
std::cout << "Works in " << company << std::endl;
}
private:
std::string company;
};
int main()
{
Employee tom{"Tom", 38, "Google"};
tom.print();
}
Aici, apelul:
Person::print();
reprezintă apelul funcției print din clasa de bază Person. Rezultatul afișat în consolă va fi:
Name: Tom Age: 38
Works in Google
Ascunderea variabilelor
O clasă derivată poate avea variabile cu același nume ca cele din clasa de bază. Deși astfel de situații pot cauza confuzii și probabil nu sunt cea mai bună practică de denumire, totuși sunt permise. De exemplu:
#include <iostream>
class Integer
{
public:
Integer(unsigned value): value(value)
{ }
void printInteger() const
{
std::cout << value << std::endl;
}
protected:
unsigned value;
};
class Decimal: public Integer
{
public:
Decimal(unsigned i_value, unsigned d_value): Integer(i_value), value(d_value)
{ }
void printDecimal() const
{
std::cout << Integer::value << "." << value << std::endl;
}
protected:
unsigned value;
};
int main()
{
Decimal decimal{12345, 3456};
decimal.printInteger(); // 12345
decimal.printDecimal(); // 12345.3456
}
Aici, clasa Integer reprezintă un număr întreg, a cărui valoare este stocată în variabila value. Această clasă este moștenită de clasa Decimal, care reprezintă un număr zecimal. Partea întreagă este stocată în câmpul value al clasei Integer, iar pentru partea zecimală este definită o variabilă value proprie în Decimal.
Deși variabila value din Integer este protected și am putea avea acces la ea în Decimal, totuși, fiind definită o variabilă cu același nume în Decimal, aceasta o ascunde pe cea din Integer. Pentru a accesa totuși variabila value din clasa de bază, trebuie să folosim operatorul :::
baza::variabilă
De exemplu:
Integer::value
Este important de reținut că în acest mod putem accesa doar variabilele declarate ca public sau protected. Nu putem accesa astfel variabilele private din clasa de bază.