C# PRZEŁADOWANIE


Witam, witam! Jak wspominałem w poprzedniej lekcji, w dzisiejszej zajmiemy się tzn. przeładowaniem metod i nie tylko, bo w C# można przeładować wiele rzeczy, np. Konstruktory, operatory… Zacznijmy sobie od pytania co to jest przeładowanie. A więc czasem będziesz potrzebował napisać w C# taką metodę która nie różni się zbytnio działaniem od innej metody tylko pobiera inne parametry. O.K na pewno z tych dwudziestu trzech wyrazów które napisałem wcześniej nic nie rozumiesz -  to normalne, puki co. Ale aby temu zapobiec, spróbujemy to jakoś obrazowo przedstawić. Wyobraź sobie, że piszesz klasę matematyczną, w tej klasie zawrzesz metodę o nazwie Kwadrat, która to pobiera parametr jakąś liczbę poczym zwraca nam jej kwadrat, ta metoda ma pobierać wszystkie możliwe liczbowe zmienne, wygląda na to że byś musiał tworzyć taki zapis:
public int Kwadrat_int(int a)
{
return a * a ;
}

public double Kwadrat_double(double a)
{
return a * a ;

}

I tak dalej…

W taki zapisie, podczas wywoływania metody jest bardzo łatwo o pomyłkę, jeszcze tym bardziej może się zdarzyć jeżeli ty nie do  końca decydujesz która metoda ma zostać wywołana, jeżeli jest wszystko pod kontrolą programu, należy tak go napisać, aby on sam wiedział jaki typ ma wybrać metody. A więc nasza klasa będzie wyglądać następująco:
class Matematyka
{

public int Kwadrat(int a)
{
return a * a ;
}

public double Kwadrat(double a)
{
return a * a ;
}

}

Co tutaj zrobiliśmy? A więc na pierwszy rzut oka może ci się wydawać że popełniliśmy błąd. A jednak nie, otóż nie popełniliśmy błędu ponieważ nasze metody pobierają różne parametry, mimo tego że mają takie same nazwy to nie błąd, program podczas wykonywania po prostu sam zdecyduje jaką metodę wybrać podczas wywołania metody Kwadrat.
Matematyka t1 = new Matematyka() ;
int a = t1.Kwadrat(10);

Jeżeli byś my napisali np. Console.WriteLine(„Liczba” + t1.Kwadrat(10)); lub Console.WriteLine(„Liczba” + t1.Kwadrat(167.8904)): nie było by żadnego błędu, ponieważ w czasie rzeczywistym program sam decyduje jaką metodę wybrać. To jest bardzo pomoce, jak zauważysz w dalszych lekcjach.

Nie możesz sobie od tak nagle zaraz pisać wszystkich metod z taką samą nazwą, jest właściwie jedna zasada której to musisz się trzymać, otóż czy to metoda czy konstruktor przeładowywane one muszą się różnić od siebie pobieranymi parametrami! I tylko tym, nie ma na to wpływu typ zwracany. Np. jeżeli byś napisał:
class Matematyka
{

public int Kwadrat(int a)
{
return a * a ;
}

public double Kwadrat(int a)
{
return a * a ;
}

}

To jest błąd, ponieważ metody i inne składniki przeładowywane muszą się różnić typem pobieranych parametrów lub ich ilością, np. prawidłowe jest takie wykonanie metody:


class Matematyka
{

public int Kwadrat(int a)
{
return a * a ;
}

public double Kwadrat(int a, int b)
{
Console.WriteLine(„B wynosi”+b);
return a * a ;
}

}

Ten zapis powyżej jest prawidłowy tyle, że w tym wypadku nie mieliśmy co zrobić ze zmienną b, ponieważ metoda ma za zadanie zwracać kwadrat liczby. Jak na razie rozumiesz co na to daje, jest to potężny mechanizm. Jak wspominałem wcześniej można przeładować konstruktory. Teraz przeładujemy konstruktor naszej poprzedniej klasy Pojazd, jak pamiętasz mieliśmy tam konstruktor który pobierał 3 parametry, dodamy konstruktor który nie pobiera żadnego parametru oraz jeden o zmienionym typie parametru od pierwszego:
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 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);


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”);
maluch.Czy_zmiesci(12);
maluch.Czy_zmiesci(2);
}

}
Koniec kodu:

Dzięki konstruktorowi który nie pobiera parametru uchroniliśmy się przed błędem, oraz mamy szybki mechanizm konstruowania obiektów. W ostatnim konstruktorze zmieniliśmy typ pobieranego parametru pojemności, dlatego że gdyby ktoś posiadał bardzo dokładną wartość tej pojemności i akurat taką chciał by zapisać, to dlaczego ma tego nie zrobić. Zapis Math.Round(double a); zwraca nam zaokrągloną liczbę double, a dzięki rzutowaniu (int) zapisujemy ją do pojemności, musimy korzystać z zaokrąglania bo jakbyśmy przypisali na samym rzutowaniu np. do zmiennej int a wartość 10.98 to ‘a’ i tak będzie posiadała wartość 10 ponieważ wartość po przecinku jest „ucinana”. O.K to na razie tyle o przeładowywaniu, jest to bardzo ważny mechanizm w C#, dlatego warto abyś go sobie bardzo dobrze przyswoił.

Jako takie małe zadanie spróbuj poszukać kilka zastosowań dla naszego przeładowania.