Dziedziczenie w C ++
Jedną z najważniejszych koncepcji programowania obiektowego jest dziedziczenie. Dziedziczenie pozwala nam zdefiniować klasę pod względem innej klasy, co ułatwia tworzenie i utrzymywanie aplikacji. Daje to również możliwość ponownego wykorzystania funkcjonalności kodu i szybkiego czasu implementacji.
Tworząc klasę, zamiast pisać zupełnie nowe składowe danych i funkcje składowe, programista może wyznaczyć, że nowa klasa powinna dziedziczyć składowe istniejącej klasy. Ta istniejąca klasa nosi nazwębase class, a nowa klasa jest nazywana derived klasa.
Idea dziedziczenia implementuje is azwiązek. Na przykład, ssak IS-A zwierzę, pies IS-A ssak, stąd też pies IS-A zwierzę i tak dalej.
Klasy bazowe i pochodne
Klasa może pochodzić z więcej niż jednej klasy, co oznacza, że może dziedziczyć dane i funkcje z wielu klas bazowych. Aby zdefiniować klasę pochodną, używamy listy pochodnych klas, aby określić klasy bazowe. Lista pochodnych klas zawiera nazwę jednej lub więcej klas bazowych i ma postać -
class derived-class: access-specifier base-class
Gdzie specyfikator dostępu jest jednym z public, protected, lub private, a klasa bazowa to nazwa wcześniej zdefiniowanej klasy. Jeśli specyfikator dostępu nie jest używany, domyślnie jest prywatny.
Rozważ klasę bazową Shape i jej klasa pochodna Rectangle w następujący sposób -
#include <iostream>
using namespace std;
// Base class
class Shape {
public:
void setWidth(int w) {
width = w;
}
void setHeight(int h) {
height = h;
}
protected:
int width;
int height;
};
// Derived class
class Rectangle: public Shape {
public:
int getArea() {
return (width * height);
}
};
int main(void) {
Rectangle Rect;
Rect.setWidth(5);
Rect.setHeight(7);
// Print the area of the object.
cout << "Total area: " << Rect.getArea() << endl;
return 0;
}
Kiedy powyższy kod jest kompilowany i wykonywany, daje następujący wynik -
Total area: 35
Kontrola dostępu i dziedziczenie
Klasa pochodna może uzyskać dostęp do wszystkich nieprywatnych elementów członkowskich swojej klasy bazowej. W związku z tym elementy członkowskie klasy bazowej, które nie powinny być dostępne dla funkcji składowych klas pochodnych, powinny być zadeklarowane jako prywatne w klasie bazowej.
Możemy podsumować różne typy dostępu według - kto może uzyskać do nich dostęp w następujący sposób -
Dostęp | publiczny | chroniony | prywatny |
---|---|---|---|
Sama klasa | tak | tak | tak |
Klasy pochodne | tak | tak | Nie |
Zajęcia pozalekcyjne | tak | Nie | Nie |
Klasa pochodna dziedziczy wszystkie metody klasy bazowej z następującymi wyjątkami -
- Konstruktory, destruktory i konstruktory kopiujące klasy bazowej.
- Przeciążone operatory klasy bazowej.
- Zaprzyjaźnione funkcje klasy bazowej.
Rodzaj dziedziczenia
Podczas wyprowadzania klasy z klasy bazowej, klasa bazowa może być dziedziczona za pośrednictwem public, protected lub privatedziedzictwo. Typ dziedziczenia jest określony przez specyfikator dostępu, jak wyjaśniono powyżej.
Rzadko używamy protected lub private dziedziczenie, ale publicdziedziczenie jest powszechnie stosowane. Podczas korzystania z innego rodzaju dziedziczenia obowiązują następujące zasady -
Public Inheritance - Wyprowadzając klasę z pliku public klasa bazowa, public stają się członkami klasy bazowej public członkowie klasy pochodnej i protected stają się członkami klasy bazowej protectedczłonkowie klasy pochodnej. Klasa bazowaprivate elementy członkowskie nigdy nie są dostępne bezpośrednio z klasy pochodnej, ale można uzyskać do nich dostęp za pośrednictwem wywołań do public i protected członkowie klasy bazowej.
Protected Inheritance - W przypadku wyprowadzenia z pliku protected klasa bazowa, public i protected stają się członkami klasy bazowej protected członkowie klasy pochodnej.
Private Inheritance - W przypadku wyprowadzenia z pliku private klasa bazowa, public i protected stają się członkami klasy bazowej private członkowie klasy pochodnej.
Dziedziczenie wielokrotne
Klasa C ++ może dziedziczyć elementy członkowskie z więcej niż jednej klasy, a oto rozszerzona składnia -
class derived-class: access baseA, access baseB....
Gdzie dostęp jest jednym z public, protected, lub privatei zostaną podane dla każdej klasy bazowej i zostaną oddzielone przecinkiem, jak pokazano powyżej. Wypróbujmy następujący przykład -
#include <iostream>
using namespace std;
// Base class Shape
class Shape {
public:
void setWidth(int w) {
width = w;
}
void setHeight(int h) {
height = h;
}
protected:
int width;
int height;
};
// Base class PaintCost
class PaintCost {
public:
int getCost(int area) {
return area * 70;
}
};
// Derived class
class Rectangle: public Shape, public PaintCost {
public:
int getArea() {
return (width * height);
}
};
int main(void) {
Rectangle Rect;
int area;
Rect.setWidth(5);
Rect.setHeight(7);
area = Rect.getArea();
// Print the area of the object.
cout << "Total area: " << Rect.getArea() << endl;
// Print the total cost of painting
cout << "Total paint cost: $" << Rect.getCost(area) << endl;
return 0;
}
Kiedy powyższy kod jest kompilowany i wykonywany, daje następujący wynik -
Total area: 35
Total paint cost: $2450