Dawno dawno temu, za siedmioma górami, za siedmioma lasami była sobie klasa.
Część 5. Dziedziczenie
Jak w każdej historii nadchodzi pora na kolejne pokolenie, które dziedziczy cechy swoich rodziców i rusza we własną podróż. 🙂
W C# istnieje pojęcie dziedziczenia tak jak w prawdziwym życiu. Tutaj jednak klasa może dziedziczyć tylko po jednej klasie (jednym rodzicu), a nie jak w prawdziwym życiu po 2 rodzicach.
Ale po co nam dziedziczenie w programowaniu i do czego może się przydać dziedziczenie?
Już śpieszę z odpowiedzią 🙂
Dziedziczenie pozwala nam przyspieszyć pisanie kodu oraz na pisanie klas ogólnych, na podstawie których piszemy klasy bardziej precyzyjne, co pozwala na utrzymanie większego porządku w naszym programie.
Najlepiej jest pokazać to na przykładzie. Wróćmy do naszej klasy ołówek z poprzednich części
class Ołówek
{
public Ołówek()
{
Kolor = "niebieski";
OłówekJestNaostrzony = true;
DługośćOłówkaWcm = 12;
}
public Ołówek(string kolorOłówka, int początkowaDługość, bool ołówekJestNaostrzonyNaPoczątku)
{
Kolor = kolorOłówka;
OłówekJestNaostrzony = ołówekJestNaostrzonyNaPoczątku;
DługośćOłówkaWcm = początkowaDługość;
}
public string Kolor;
public bool OłówekJestNaostrzony;
public int DługośćOłówkaWcm;
public void ZłamOłówek()
{
//złamanie ołówka
}
public void NaostrzOłówek(int naostrzOIlośćCentymetrów)
{
DługośćOłówkaWcm = DługośćOłówkaWcm - naostrzOIlośćCentymetrów;
OłówekJestNaostrzony = true;
}
public bool CzyOłówekMożnaJeszczeNaostrzyć()
{
return OłówekJestNaostrzony;
}
}
W naszym świecie Ołówek istnieje od tysięcy lat. Był już używany w starożytnym Egipcie, Grecji i Rzymie. Ale w 18 wieku został pokazany ołówek automatyczny, który można powiedzieć, że jest jego następcą (nowszą wersją).
Załóżmy więc w uproszczeniu, że mamy klasę
class Ołówek
{
public string KolorOłówka;
}
Możemy teraz zdefiniować klasę, której nadamy również właściwość kolorOłówka.
class OłówekAutomatyczny
{
public string KolorOłówka;
}
Możemy jednak użyć dziedziczenia i napisać coś takiego
class OłówekAutomatyczny : Ołówek{
}
W tym wypadku OłówekAutomatyczny odziedziczył wszystko co miała w sobie klasa Ołówek, a więc właściwość kolorOłówka, a my nie musimy jej pisać dwa razy w dwóch klasach.
Pewnie teraz rodzi się pytanie, ale to tylko jedna linijka, ale co jeżeli tak jak w przykładzie na początku linijek kodu jest kilkanaście lub kilkadziesiąt i powtarzają się one? Wtedy można zauważyć faktyczną oszczędność czasu oraz można zauważyć, że zmniejsza się ryzyko popełnienia błędu pisząc coś drugi raz.
Przykład z początku wpisu
class Ołówek
{
public Ołówek()
{
Kolor = "niebieski";
OłówekJestNaostrzony = true;
DługośćOłówkaWcm = 12;
}
public Ołówek(string kolorOłówka, int początkowaDługość, bool ołówekJestNaostrzonyNaPoczątku)
{
Kolor = kolorOłówka;
OłówekJestNaostrzony = ołówekJestNaostrzonyNaPoczątku;
DługośćOłówkaWcm = początkowaDługość;
}
public string Kolor;
public bool OłówekJestNaostrzony;
public int DługośćOłówkaWcm;
public void ZłamOłówek()
{
//złamanie ołówka
}
public void NaostrzOłówek(int naostrzOIlośćCentymetrów)
{
DługośćOłówkaWcm = DługośćOłówkaWcm - naostrzOIlośćCentymetrów;
OłówekJestNaostrzony = true;
}
public bool CzyOłówekMożnaJeszczeNaostrzyć()
{
return OłówekJestNaostrzony;
}
}
Teraz zamiast pisać
class OłówekAutomatyczny
{
public OłówekAutomatyczny()
{
Kolor = "niebieski";
OłówekJestNaostrzony = true;
DługośćOłówkaWcm = 12;
}
public OłówekAutomatyczny(string kolorOłówka, int początkowaDługość, bool ołówekJestNaostrzonyNaPoczątku)
{
Kolor = kolorOłówka;
OłówekJestNaostrzony = ołówekJestNaostrzonyNaPoczątku;
DługośćOłówkaWcm = początkowaDługość;
}
public string Kolor;
public bool OłówekJestNaostrzony;
public int DługośćOłówkaWcm;
public void ZłamOłówek()
{
//złamanie ołówka
}
public void NaostrzOłówek(int naostrzOIlośćCentymetrów)
{
DługośćOłówkaWcm = DługośćOłówkaWcm - naostrzOIlośćCentymetrów;
OłówekJestNaostrzony = true;
}
public bool CzyOłówekMożnaJeszczeNaostrzyć()
{
return OłówekJestNaostrzony;
}
}
Wystarczy, że napiszemy
class OłówekAutomatyczny : Ołówek{
}
I mamy wszystkie metody oraz właściwości metody Ołówek odziedziczone w klasie OłówekAutomatyczny
Teraz widać, ile kodu można zaoszczędzić.
Idźmy o krok dalej 🙂
Załóżmy, że mamy do zrobienia program, który posiada informacje o przyrządach do pisania.
Oprócz ołówka i ołówka automatycznego mamy jeszcze długopis, flamaster, pióro, kredka i wiele innych. Jeżeli każda klasa miałaby zajmować np. 50 linijek kodu, wtedy mając 6 przedmiotów do pisania wypisanych przed chwilą mielibyśmy 6 x 50 co daje 300 linii kodu do napisania.
Za pomocą dziedziczenia musimy napisać 50 linii, a następnie dla każdego z przedmiotów piszących wystarczy, że użyjemy 2 linii kodu jak w poprzednim przykładzie
class OłówekAutomatyczny : Ołówek{
}
Nasz kod będzie więc zajmował 50 (pierwszy przedmiot piszący) + 5 (pozostałe 5 przedmiotów do pisania)*2 (2 linie na każdy z przedmiotów) = 60 linii. Zaoszczędzamy więc 240 linii kodu, których nie trzeba będzie pisać 🙂
Pojęcie dziedziczenia to podstawa w językach obiektowych i praktycznie obowiązkowe pytanie na rozmowach kwalifikacyjnych zwłaszcza dla początkujących (stażystów, praktykantów i juniorów), więc warto zrozumieć jak działa dziedziczenie i do czego się przydaje.
Mam nadzieję, że przedstawiłem pojęcie dziedziczenia w sposób prosty i zrozumiały. Podziel się swoją opinią na temat dziedziczenia w komentarzu lub pisząc do mnie prywatnie 🙂
To be continued …