C# DZIEDZICZENIE


Lekcja którą teraz przerabiasz tyczy się pojęcia dziedziczenia. Jest to bardzo szeroki temat i omówimy go po części w kilku lekcjach począwszy od tej. Dzięki procesowi dziedziczenia możemy sprawić, że jedna z klasy dziedziczy składniki z klasy bazowej dodając nowe swoje składnik, unikalne dla niej samej. Postaram ci wytłumaczyć działanie dziedziczenia bardziej obrazowo. Otóż wyobraźmy sobie klasę Jedzenie, która to posiada takie właściwości jak, jadalność, kolor, smak, zapach itp. Teraz wyprowadzamy klasę Owoc która dziedziczy wszystkie składniki z klasy Jedzenie dodając swoje unikalne jak np. soczystość, czy_owoc_tropikalny itp. Teraz wyprowadzamy kolejną klasę: Jabłko która to dziedziczy wszystkie składniki z klasy Owoc oraz dodają swoje unikalne składniki takie jak: rośnie_na_drzewie, rodzaj, odmiana itp. Teraz klasa Jabłko posiada wszystkie składniki jakie odziedziczyła z klasy Owoc oraz te składniki z klasy Jedzenie gdyż, dziedzicząc z klasy Owoc odziedziczyła te składniki które dziedziczyła klasa Owoc czyli składniki klasy Jedzenie. Jest to logiczne gdyż każde jedzenie posiada zapach, lub każde Jabłko rośnie na drzewie, ale nie każde jedzenie rośnie na drzewie. Na poniższej ilustracji ukazane które składniki posiada dana klasa.

Dziedziczenie w C#

Po wnikliwej interpretacji ilustracji z twojej strony masz już jakieś wyobrażenie tego co będziemy robić. Ale zanim zaczniemy pisać programy, to musimy jeszcze powiedzieć o jednej rzeczy, klasa której składniki są dziedziczone nazywamy klasą bazową, a klasę która dziedziczy te składniki nazywamy klasą wyprowadzoną. Teraz przejdziemy do jakiegoś prostego przykładu, może mało funkcjonalnego, ale ma on za zadanie ukazania tobie jak to dziedziczenie przebiega. Jeszcze wspomnę o tym jak wygląda deklaracja klasy wyprowadzonej:

class nazwa_klasy_wyprowadzonej : nazwa_klasy_bazowej

{

…..

}

Co to jest klasa wyprowadzona i co to jest klasa bazowa, wiesz bo zostało to opisane powyżej, ważne abyś miał jakieś wyobrażenie zapisu. Dobrze już przechodzimy do przykładu:

Początek kodu:


using System;


class X
{
public int a;
}


class Y : X
{
public int b;
}


class Pokaz
{
public static void Main()
{
Y y = new Y();
y.a = 124;
y.b = 4;


Console.WriteLine(„a wynosi : ” + y.a);
Console.WriteLine(„b wynosi : ” + y.b);
}

}

Koniec kodu:

W powyższym przykładzie w klasie X deklarujemy zmienną x typu int, klasa Y dziedziczy po klasie X zmienną x oraz posiada własną zmienną y. Jak widzisz po utworzeniu obiektu klasy Y mamy dostęp do zmiennej x, którą to dziedziczymy. O.K teraz mniej więcej widzisz na czym to polega, na razie wydaję się to tobie mało pożyteczne, ale nic bardziej mylnego. Ukażę ci jeszcze jeden prosty przykład w którym to znajduję się jeszcze metoda, aby ukazać ci, że dziedziczone są wszystkie składniki klas nie tylko zmienne.

Początek kodu:
using System;


class X
{
public int a;


public void Metoda1()
{
Console.WriteLine(„Metoda1() – Zostaje wywołana”);
}
}


class Y : X
{
public int b;
}


class Pokaz
{
public static void Main()
{
Y y = new Y();
y.a = 124;
y.b = 4;
y.Metoda1();


Console.WriteLine(„a wynosi : ” + y.a);
Console.WriteLine(„b wynosi : ” + y.b);
}

}

Koniec kodu:

A więc sam zauważyłeś, że klasa Y odziedziczyła nawet metodę z klasy bazowej (klasy X). Na razie to o czym mówimy tutaj to postawy. Ale już możemy wykorzystać to w jakiś pożyteczny sposób. Jak pamiętasz w poprzednich lekcjach napisaliśmy klasę Pojazd, teraz wyprowadzimy z tej klasy klasę Ciezarowka (Ciężarówka) która to odziedziczy wszystkie składniki klasy Pojazd (przecież każda ciężarówka jest pojazdem) oraz doda swoje własne składniki jak na przykład: Tonaż. Użyję klasy Pojazd z poprzednich lekcji dodając tylko nową klasę Ciezarowka. Oto przykład:

Początek kodu:
using System;


class Pojazd
{
public int liczba_pasazerow;
public int pojemnosc;
public double spalanie;


public Pojazd(int pasazerowie, int poj, double spalanko)
{
liczba_pasazerow = pasazerowie;
pojemnosc = poj;
spalanie = spalanko;
}


public Pojazd()
{
liczba_pasazerow = 0;
pojemnosc = 0;
spalanie = 0;
}


public Pojazd(int pasazerowie, double poj, double spalanko)
{
liczba_pasazerow = pasazerowie;
pojemnosc = (int)Math.Round(poj);
spalanie = spalanko;
}


public double Zasieg()
{
double wartosc = pojemnosc * 100 / spalanie;
return wartosc;
}


public void Czy_zmiesci(int pasazerowie)
{
if (liczba_pasazerow >= pasazerowie)
{
Console.WriteLine(„Tak zmieści się liczba ” + pasazerowie + ” pasażerów”);
}
else
{
Console.WriteLine(„Za mało miejsca dla ” + pasazerowie + ” psażerów”);
}
}
}


class Ciezarowka : Pojazd
{
public int tonaz;


public Ciezarowka(int pasazerowie, int poj, double spalanko, int tonaz_kg)
{
liczba_pasazerow = pasazerowie;
pojemnosc = poj;
spalanie = spalanko;
tonaz = tonaz_kg;
}


public void Dozwolona_masa(int masa_kg)
{
if (tonaz >= masa_kg)
{
Console.WriteLine(„Tak ciężarówka może przewieźć ” + masa_kg + ” kg”);
}
else
{
Console.WriteLine(„Nie ciężarówka niemoże przewieźć ” + masa_kg + ” kg”);
}
}
}

class Pokaz
{
public static void Main()
{


Pojazd maluch = new Pojazd();
Pojazd polonez = new Pojazd(5, 47, 9.7);
Pojazd matiz = new Pojazd(5, 34.78543, 6);


Ciezarowka Star = new Ciezarowka(3, 238, 27, 2000);
Ciezarowka Robur = new Ciezarowka(2, 272, 29, 1500);

Console.WriteLine(„Maluch pomieści ” + maluch.liczba_pasazerow + ” pasażerów”);
Console.WriteLine(„Zasięg: ” + maluch.Zasieg());

Console.WriteLine(„\n\n”);


Console.WriteLine(„Polonez pomieści ” + polonez.liczba_pasazerow + ” pasażerów”);
Console.WriteLine(„Zasięg: ” + polonez.Zasieg());

Console.WriteLine(„\n\n”);


Console.WriteLine(„Matiz pomieści ” + matiz.liczba_pasazerow + ” pasażerów”);
Console.WriteLine(„Zasięg: ” + matiz.Zasieg());


Console.WriteLine(„\n\n”);


Console.WriteLine(„Star pomieści ” + Star.liczba_pasazerow + ” pasażerów”);
Console.WriteLine(„Zasięg: ” + Star.Zasieg());


Console.WriteLine(„\n\n”);


Console.WriteLine(„Robur pomieści ” + Robur.liczba_pasazerow + ” pasażerów”);
Console.WriteLine(„Zasięg: ” + Robur.Zasieg());


Console.WriteLine(„\n\n”);
Console.WriteLine(„Maluch”);
maluch.Czy_zmiesci(12);
maluch.Czy_zmiesci(2);


Console.WriteLine(„\n\nStar”);
Star.Czy_zmiesci(1);
Star.Dozwolona_masa(3412);
}

}

Koniec kodu:

W powyższym przykładzie dodaliśmy klasę Ciezarowka która to odziedziczyła wszystkie składniki z klasy Pojazd. W klasie Ciezarowka tworzymy konstruktor, w którym to przypisujemy zmiennym wartości, oczywiście że mam dostęp do zmiennych klasy Pojazd, gdyż są one publiczne(public) jeżeli by były prywatne(private) z poziomu klasy Ciezarowka nie mieli byśmy dostępu, jest jeszcze jeden specyfikator dostępu: protected który działa podobnie jak private tylko z tą różnicą że klasy wyprowadzone mają dostęp do składników, ale o tym specyfikatorze dostępu napiszę w następnych lekcjach. Czasem może zajść potrzeba wywołania konstruktora klasy bazowej, co jest o wiele efektywniejszym zabiegiem. Ale o tym zaraz, wracając jeszcze do klasy. Jej działanie nie powinno być dla ciebie trudne do zrozumienia, nasza klasa wyprowadzona dodaje także swoją własną metodę która to sprawdza czy taką masę można przewieźć naszą ciężarówką, oczywiście używamy także typowych metod dla klasy Pojazd, na przykład aby policzyć zasięg ciężarówki na pełnym baku. Teraz wrócę do tego co napisałem wcześniej o konstruktorze i o tej potrzebie wywołania konstruktora klasy bazowej. Oto jak wygląda deklaracja takiego konstruktora klasy wyprowadzonej który wywołuje konstruktor klasy bazowej.

specyfikator_dostępu nazwa_klasy_wyprowadzonej(lista_parametrów):base(lista_parametrów)
{

}

Pamiętaj o tym, że na stronie w konstruktorze nawias po słowie base przechodzi do następnej linijki jest to spowodowane szerokością kursu, normalnie ma to być w jednej linii tak jak w ogólnej interpretacji!

Specyfikator dostępu to wiadomo co to, nazwa klasy wyprowadzonej również, lista parametrów to, parametry jakie pobiera nasza konstruktor, teraz po „:” piszemy słowo base informując że mamy zamiar przesłać jakieś argumenty konstruktorowi bazowemu. Jak to wygląda w praktyce prześledź sobie na poniższym przykładzie w którym to jest zmodyfikowany program z klasa Ciezarowka.

Początek kodu:
using System;


class Pojazd
{
public int liczba_pasazerow;
public int pojemnosc;
public double spalanie;

public Pojazd(int pasazerowie, int poj, double spalanko)
{
liczba_pasazerow = pasazerowie;
pojemnosc = poj;
spalanie = spalanko;
}

public Pojazd()
{
liczba_pasazerow = 0;
pojemnosc = 0;
spalanie = 0;
}

public Pojazd(int pasazerowie, double poj, double spalanko)
{
liczba_pasazerow = pasazerowie;
pojemnosc = (int)Math.Round(poj);
spalanie = spalanko;
}


public double Zasieg()
{
double wartosc = pojemnosc * 100 / spalanie;
return wartosc;
}

public void Czy_zmiesci(int pasazerowie)
{
if (liczba_pasazerow >= pasazerowie)
{
Console.WriteLine(„Tak zmieści się liczba ” + pasazerowie + ” pasażerów”);
}
else
{
Console.WriteLine(„Za mało miejsca dla ” + pasazerowie + ” psażerów”);
}
}
}


class Ciezarowka : Pojazd
{
public int tonaz;


public Ciezarowka(int pasazerowie, int poj, double spalanko, int tonaz_kg):base(pasazerowie,poj,spalanko)
{
tonaz = tonaz_kg;
}


public void Dozwolona_masa(int masa_kg)
{
if (tonaz >= masa_kg)
{
Console.WriteLine(„Tak ciężarówka może przewieźć ” + masa_kg + ” kg”);
}
else
{
Console.WriteLine(„Nie ciężarówka niemoże przewieźć ” + masa_kg + ” kg”);
}
}
}

class Pokaz
{
public static void Main()
{

{


Pojazd maluch = new Pojazd();
Pojazd polonez = new Pojazd(5, 47, 9.7);
Pojazd matiz = new Pojazd(5, 34.78543, 6);


Ciezarowka Star = new Ciezarowka(3, 238, 27, 2000);
Ciezarowka Robur = new Ciezarowka(2, 272, 29, 1500);


Console.WriteLine(„Maluch pomieści ” + maluch.liczba_pasazerow + ” pasażerów”);
Console.WriteLine(„Zasięg: ” + maluch.Zasieg());

Console.WriteLine(„\n\n”);


Console.WriteLine(„Polonez pomieści ” + polonez.liczba_pasazerow + ” pasażerów”);
Console.WriteLine(„Zasięg: ” + polonez.Zasieg());


Console.WriteLine(„\n\n”);


Console.WriteLine(„Matiz pomieści ” + matiz.liczba_pasazerow + ” pasażerów”);
Console.WriteLine(„Zasięg: ” + matiz.Zasieg());


Console.WriteLine(„\n\n”);


Console.WriteLine(„Star pomieści ” + Star.liczba_pasazerow + ” pasażerów”);
Console.WriteLine(„Zasięg: ” + Star.Zasieg());


Console.WriteLine(„\n\n”);


Console.WriteLine(„Robur pomieści ” + Robur.liczba_pasazerow + ” pasażerów”);
Console.WriteLine(„Zasięg: ” + Robur.Zasieg());


Console.WriteLine(„\n\n”);
Console.WriteLine(„Maluch”);
maluch.Czy_zmiesci(12);
maluch.Czy_zmiesci(2);


Console.WriteLine(„\n\nStar”);
Star.Czy_zmiesci(1);
Star.Dozwolona_masa(3412);
}

}

Koniec kodu:

Teraz wywołujemy konstruktor klasy bazowej, poprzez przesłanie do niego argumentów jakie pobraliśmy, przypisaniem ich do odpowiednich zmiennych zajmie się już konstruktor klasy bazowej. Nie jest konieczne pobieranie takich samych nazwa parametrów jak klasa bazowo, oto jak by mógł wyglądać nasz konstruktor klasy wyprowadzonej:

public Ciezarowka(int pasazerowie_TIR, int poj_TIR, double spalanko_TIR, int tonaz_kg):base(pasazerowie_TIR,poj_TIR,spalanko_TIR)
{
tonaz = tonaz_kg;
}

Teraz poprawimy naszą klasę dodając od niej jeszcze konstruktor dla klasy Ciezarowka który to nie pobiera parametrów, oraz tą która pobiera pojemność w double.

Początek kodu:
using System;


class Pojazd
{
public int liczba_pasazerow;
public int pojemnosc;
public double spalanie;


public Pojazd(int pasazerowie, int poj, double spalanko)
{
liczba_pasazerow = pasazerowie;
pojemnosc = poj;
spalanie = spalanko;
}

public Pojazd()
{
liczba_pasazerow = 0;
pojemnosc = 0;
spalanie = 0;
}

public Pojazd(int pasazerowie, double poj, double spalanko)
{
liczba_pasazerow = pasazerowie;
pojemnosc = (int)Math.Round(poj);
spalanie = spalanko;
}

public double Zasieg()
{
double wartosc = pojemnosc * 100 / spalanie;
return wartosc;
}


public void Czy_zmiesci(int pasazerowie)
{
if (liczba_pasazerow >= pasazerowie)
{
Console.WriteLine(„Tak zmieści się liczba ” + pasazerowie + ” pasażerów”);
}
else
{
Console.WriteLine(„Za mało miejsca dla ” + pasazerowie + ” psażerów”);
}
}
}


class Ciezarowka : Pojazd
{
public int tonaz;


public Ciezarowka(int pasazerowie_TIR, int poj_TIR, double spalanko_TIR, int tonaz_kg):base(pasazerowie_TIR,poj_TIR,spalanko_TIR)
{
tonaz = tonaz_kg;
}


public Ciezarowka(): base()
{
tonaz = 0;
}


public Ciezarowka(int pasazerowie_TIR, double poj_TIR, double spalanko_TIR, int tonaz_kg)
: base(pasazerowie_TIR, poj_TIR, spalanko_TIR)
{
tonaz = tonaz_kg;
}


public void Dozwolona_masa(int masa_kg)
{
if (tonaz >= masa_kg)
{
Console.WriteLine(„Tak ciężarówka może przewieźć ” + masa_kg + ” kg”);
}
else
{
Console.WriteLine(„Nie ciężarówka niemoże przewieźć ” + masa_kg + ” kg”);
}
}
}

class Pokaz
{
public static void Main()
{


Pojazd maluch = new Pojazd();
Pojazd polonez = new Pojazd(5, 47, 9.7);
Pojazd matiz = new Pojazd(5, 34.78543, 6);


Ciezarowka Star = new Ciezarowka(3, 238, 27, 2000);
Ciezarowka Robur = new Ciezarowka(2, 272, 29, 1500);


Console.WriteLine(„Maluch pomieści ” + maluch.liczba_pasazerow + ” pasażerów”);
Console.WriteLine(„Zasięg: ” + maluch.Zasieg());


Console.WriteLine(„\n\n”);


Console.WriteLine(„Polonez pomieści ” + polonez.liczba_pasazerow + ” pasażerów”);
Console.WriteLine(„Zasięg: ” + polonez.Zasieg());

Console.WriteLine(„\n\n”);

Console.WriteLine(„Matiz pomieści ” + matiz.liczba_pasazerow + ” pasażerów”);
Console.WriteLine(„Zasięg: ” + matiz.Zasieg());

Console.WriteLine(„\n\n”);


Console.WriteLine(„Star pomieści ” + Star.liczba_pasazerow + ” pasażerów”);
Console.WriteLine(„Zasięg: ” + Star.Zasieg());


Console.WriteLine(„\n\n”);


Console.WriteLine(„Robur pomieści ” + Robur.liczba_pasazerow + ” pasażerów”);
Console.WriteLine(„Zasięg: ” + Robur.Zasieg());

Console.WriteLine(„\n\n”);
Console.WriteLine(„Maluch”);
maluch.Czy_zmiesci(12);
maluch.Czy_zmiesci(2);


Console.WriteLine(„\n\nStar”);
Star.Czy_zmiesci(1);
Star.Dozwolona_masa(3412);
}

}

Koniec kodu:

Teraz możemy powiedzieć, że mamy w pełni funkcjonalną klasę Ciezarowka. Ta lekcja była długa, ale ważne abyś przyswoił sobie wszystko czego się nauczyłeś, postaraj się napisać kilka klas, mogą być do powyższego programu, może wyprowadź kolejną klasę z Klasy pojazd, np. Koparka, Bo przecież z jednej klasy może dziedziczyć wiele klas, ale klasa wprowadzona może mieć tylko jedną klasę bazową. To tyle, to nie koniec dziedziczenia, będziemy o nim pisać w następnych lekcjach.