Dziedziczenie
Często w naszych programach istnieją bardzo podobne klasy, które różnią się jedynie małymi szczegółami. Dla przykładu: klasa Wojownik, Mag i Łucznik. Wszyscy będą mieli podobne atrybuty takie jak życie, poziom, nazwa itp. W ten sposób powstanie nam masa klas posiadających w wielu miejscach dokładnie taki sam kod, czego byśmy nie chcieli.
class Wojownik
{
private:
string nazwa;
int hp;
int mp;
int poziom;
int sila;
public:
void OkrzykBojowy()
{
cout << "Argh!";
}
void AtakMieczem()
{
//kod
}
//gettery i settery
};
class Lucznik
{
private:
string nazwa;
int hp;
int mp;
int poziom;
int zrecznosc;
public:
void OkrzykBojowy()
{
cout << "Argh!";
}
void AtakLukiem()
{
//kod
}
//gettery i settery
};
class Mag
{
private:
string nazwa;
int hp;
int mp;
int poziom;
int silaWoli;
public:
void OkrzykBojowy()
{
cout << "Argh!";
}
void MagicznyAtak()
{
//kod
}
//gettery i settery
};
Nie wygląda to imponująco, nie pisałem getterów, setterów i konstruktora a i tak kod wygląda na zbyt bardzo powtórzony i bezsensowny. Aby rozwiązać ten problem będziemy dziedziczyć klasę z innej klasy:
class Bohater
{
protected:
string nazwa;
int hp;
int mp;
int poziom;
public:
void OkrzykBojowy()
{
cout << "Argh!";
}
//gettery i settery
};
class Wojownik : public Bohater
{
private:
int sila;
public:
void AtakMieczem()
{
//kod
}
};
class Lucznik : public Bohater
{
private:
int zrecznosc;
public:
void AtakLukiem()
{
//kod
}
};
class Mag : public Bohater
{
private:
int silaWoli;
public:
void MagicznyAtak()
{
//kod
}
};
Operatorem dwukropka informujemy, że nasza nowa klasa po lewej stronie ma odziedziczyć cechy po tej z prawej strony. Public po dwukropku to typ dziedziczenia o czym za chwilę napiszę. Jeżeli w klasie pochodnej chcielibyśmy nieco zmodyfikować odziedziczoną metodę, piszemy ją na nowo a ona sama zostanie nadpisana.
Określanie dostępu do składników w klasie podstawowej
private:
zostaną odziedziczone, w klasi pochodnej dalej będą prywatne.
public i protected:
są bezpośrednio dostępne w klasie pochodnej. Protected znaczy, że dla wszystkich potomków tej klasy będzie on jak public, a dla reszty niedostępny czyli jak private.
Rodzaje dziedziczenia
public:
składniki public z klasy podstawowej mają w klasie pochodnej również public, protected również zostaną protected (nic się nie zmienia)
protected:
składniki public i protected są w klasie pochodnej zabezpieczone jako protected
private:
składniki public oraz protected są w klasie pochodnej od teraz private
Co nie jest dziedziczone
- Konstruktor
- Destruktor
- Operator przypisania (=)
Konstruktor w klasie pochodnej
Konstruktor musimy napisać sami, ponieważ każda klasa pochodna różni się między sobą. Aby nie przepisywać od nowa atrybutów klasy podstawowej robimy coś takiego:
Bohater(string _nazwa, int _hp, int _mp, int _poziom) //konstruktor w klasie Bohater
{
nazwa = _nazwa;
hp = _hp;
mp = _mp;
poziom = _poziom;
}
Wojownik( string nazwa, int hp, int mp, int poziom, int _sila) : Bohater(nazwa, hp, mp, poziom) //konstruktor w klasie Wojownik
{
sila = _sila;
}
Dodatkowo możemy ustawić wartości domyśle, które przyjmą się jeżeli sami nie wprowadzimy naszych podczas tworzenia obiektu: (tak można robić z każdym konstruktorem, w klasie podstawowej również)
Wojownik( string nazwa = "Wojo", int hp = 100, int mp = 20, int poziom = 1, int _sila = 20) : Bohater(nazwa, hp, mp, poziom)
{
sila = _sila;
}
Dodatki
Do zaprezentowania dziedziczenia konstruktora w klasie pochodnej użyłem preambuły konstruktora, prościej listy inicjalizacyjnej.
Kompletny kod pliku main.cpp (click)