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 …