Historia wymaga pasterzy, nie rzeźników.

Argumenty i przeciążanie metod
127
Przeciążanie metod
W trakcie naszej pracy nad kodem klasy Punkt powstały dwie metody o takiej samej nazwie, ale różnym kodzie. Chodzi oczywiście o metody ustawXY. Pierwsza wersja przyjmowała jako argumenty dwie liczby typu int, a druga miała tylko jeden argument, którym był obiekt klasy Punkt. Okazuje się, że takie dwie metody mogą współistnieć w klasie Punkt i z obu z nich możemy korzystać w kodzie programu.
Ogólnie rzecz ujmując, w każdej klasie może istnieć dowolna liczba metod, które mają takie same nazwy, o ile tylko różnią się argumentami. Mogą one — ale nie muszą —
również różnić się typem zwracanego wyniku. Nazywamy to przeciążaniem metod.
Skonstruujmy zatem taką klasę Punkt, w której znajdą się obie wersje metody ustawXY.
Kod tej klasy jest przedstawiony na listingu 3.18.
Listing 3.18. Przeciążone metody UstawXY w klasie Punkt
class Punkt
{ int x;
int y;
void ustawXY(int wspX, int wspY)
{
x = wspX;
y = wspY;
}
void ustawXY(Punkt punkt)
{
x = punkt.x;
y = punkt.y;
}
}
Klasa ta zawiera w tej chwili dwie przeciążone metody o nazwie ustawXY. Jest to moż-
liwe, ponieważ przyjmują one różne argumenty: pierwsza metoda — dwie liczby typu int, druga — jeden obiekt klasy Punkt. Obie metody realizują takie samo zadanie, tzn.
ustawiają nowe wartości w polach x i y. Możemy przetestować ich działanie, dopisując do klasy Punkt metodę Main w postaci widocznej na listingu 3.19.
Listing 3.19. Metoda Main do klasy Punkt z listingu 3.18
public static void Main()
{
Punkt punkt1 = new Punkt();
Punkt punkt2 = new Punkt();
punkt1.ustawXY(100, 100);
punkt2.ustawXY(200,200);
System.Console.WriteLine("Po pierwszym ustawieniu współrzędnych:"); System.Console.WriteLine("x = " + punkt1.x);
System.Console.WriteLine("y = " + punkt1.y);
System.Console.WriteLine("");
128
Rozdział 3. ♦ Programowanie obiektowe
punkt1.ustawXY(punkt2);
System.Console.WriteLine("Po drugim ustawieniu współrzędnych:"); System.Console.WriteLine("x = " + punkt1.x);
System.Console.WriteLine("y = " + punkt1.y);
}
Działanie tej metody jest proste i nie wymaga wielu wyjaśnień. Tworzymy na począt-ku dwa obiekty klasy Punkt i przypisujemy je zmiennym punkt1 oraz punkt2. Następnie korzystamy z pierwszej wersji przeciążonej metody ustawXY, aby przypisać polom x i y pierwszego obiektu wartość 100, a polom x i y drugiego obiektu — 200. Dalej wyświetlamy zawartość obiektu punkt1 na ekranie. Potem wykorzystujemy drugą wersję metody ustawXY w celu zmiany zawartości pól obiektu punkt1, tak aby zawierały wartości zapisane w obiekcie punkt2. Następnie ponownie wyświetlamy wartości pól obiektu punkt1 na ekranie.
Argumenty metody Main
Każdy program musi zawierać punkt startowy, czyli miejsce, od którego zacznie się jego wykonywanie. W C# takim miejscem jest metoda o nazwie Main i następującej deklaracji: public static void Main()
{
// treść metody Main
}
Jeśli w danej klasie znajdzie się metoda w takiej postaci, od niej właśnie zacznie się wykonywanie kodu programu. Teraz powinno być już jasne, dlaczego dotychczas prezentowane przykładowe programy miały schematyczną konstrukcję:
class Program
{ public static void main()
{
// tutaj instrukcje do wykonania
}
}
Ta konstrukcja może mieć również nieco inną postać. Otóż metoda Main może przyjąć argument, którym jest tablica ciągów znaków. Zatem istnieje również jej przeciążona wersja o schematycznej postaci:
public static void Main(String[] args)
{ // treść metody Main
}
Tablica args zawiera parametry wywołania programu, czyli argumenty przekazane z wiersza poleceń. O tym, że tak jest w istocie, możemy przekonać się, uruchamiając program widoczny na listingu 3.20. Wykorzystuje on pętlę for do przejrzenia i wyświe-tlenia na ekranie zawartości wszystkich komórek tablicy args. Przykładowy wynik jego działania jest widoczny na rysunku 3.8.
Lekcja 15. Argumenty i przeciążanie metod
129
Listing 3.20. Odczytanie argumentów podanych z wiersza poleceń using System;
public class Program
{
public static void Main(String[] args)
{
Console.WriteLine("Argumenty wywołania:");
for(int i = 0; i < args.Length; i++)
{
Console.WriteLine(args[i]);
}
}
}
Rysunek 3.8.
Program
wyświetlający
parametry jego
wywołania
Sposoby przekazywania argumentów
Argumenty metod domyślnie przekazywane są przez wartość. To oznacza, że wewnątrz metody dostępna jest tylko kopia argumentu i jakiekolwiek zmiany jego wartości będą wykonywane na tej kopii i obowiązywały wyłącznie wewnątrz metody. Przykładowo jeśli mamy metodę Zwieksz o postaci:
public void Zwieksz(int arg)
{ arg++;
}
i w którymś miejscu programu wywołamy ją, przekazując jako argument zmienną liczba, np. w następujący sposób:
int liczba = 100;
Zwieksz(liczba);
Console.WriteLine(liczba);
To metoda Zwieksz otrzyma do dyspozycji kopię wartości zmiennej liczba i zwiększenie wykonywane przez instrukcję arg++; będzie obowiązywało tylko w obrębie tej metody.
Instrukcja Console.WriteLine(liczba); spowoduje więc wyświetlenie wartości 100.
To zachowanie można zmienić — argumenty mogą być również przekazywane przez referencję. Metoda otrzyma wtedy w postaci argumentu referencję do zmiennej i będzie mogła bezpośrednio operować na tej zmiennej (a nie na jej kopii). W takiej sytuacji należy zastosować słowa ref lub out. Różnica jest taka, że w pierwszym przypadku
130
Rozdział 3. ♦ Programowanie obiektowe
przekazywana zmienna musi być zainicjowana przed przekazaniem jej jako argument, a w przypadku drugim musi zaś być zainicjowana wewnątrz metody. Metoda Zwieksz mogłaby mieć zatem postać:
public void Zwieksz(ref int arg)
{ arg++;
}
Wtedy fragment kodu:
int liczba = 100;
Zwieksz(ref liczba);
Console.WriteLine(liczba);

Podstrony