Lecimy z następnym tematem Javy. Weźmiemy pod lupę dwa terminy, które wbrew pozorom nie są synonimiczne: przeciążanie a przesłanianie. Bardzo podobne do siebie, a oznaczają dwie zupełnie różne rzeczy. Macie przed sobą rozmowę kwalifikacyjną na stanowisko programisty w tym języku? Bądźcie pewni, że to pytanie może paść!
Tweet |
PRZECIĄŻANIE A PRZESŁANIANIE. RÓŻNICA NIECO ZASADNICZA
Wyjaśnijmy sobie najpierw terminy:
Przeciążanie (ang. "overloading") polega na dodaniu kolejnej metody o tej samej nazwie umieszczonej w tej samej klasie (lub w drzewie dziedziczenia) różniącej się listą parametrów. W ten sposób występuje kilka różnych metod o tej samej nazwie mogących wykonywać przeróżne instrukcje. Zaznaczam od razu, że w poprzednim artykule pokazałem przykład wykorzystujący przeciążanie, a przesłanianie pokażę dopiero teraz.
Przesłanianie czy nadpisywanie (ang. "overriding") z kolei to sytuacja nadpisywania istniejącej metody pochodzącej z klasy nadrzędnej własną zawartością. To znaczy, że ta sama metoda o tych samych parametrach może wykonywać albo coś zupełnie innego, albo to samo co klasa nadrzędna, albo też może pobierać wszystkie czynności z metody "pierwotnej" + dodany własny blok kodu! W języku Java niemożliwe jest przesłanianie konstruktorów.
Łatwo można poplątać jedno z drugim. Mi też się czasami zdarza pomyłka terminów, dlatego też przypominam sobie słowa po angielsku i wtedy mi łatwiej rozróżnić: "overriding" - nadpisywanie, "overloading" - przeciążanie.
PRZECIĄŻANIE I PRZESŁANIANIE W AKCJI
Pokazywałem poprzednio przeciążanie konstruktorów, ale dla porządku zaprezentuję to jeszcze raz tylko na "zwykłych" metodach. Oto przykłady programów pokazujące jak wyglądają obie operacje. Najpierw kod pokazujący przeciążanie metod:
- KLASA "Main"
public class Main
{
public static void main(String[] args)
{
Example a = new Example();
a.printText(6);
a.printText(15.4f);
a.printText(true);
}
}
- KLASA "Example"
public class Example
{
public void printText(int n)
{
System.out.println("Wypisuję liczbę całkowitą: " + n);
}
public void printText(float n)
{
System.out.println("Wypisuję liczbę zmiennoprzecinkową: " + n);
}
public void printText(boolean n)
{
System.out.println("Wypisuję wartość logiczną: " + n);
}
}
A teraz program ukazujący przesłanianie metod:
- KLASA "Main"
public class Main
{
public static void main(String[] args)
{
ExampleParent p = new ExampleParent();
ExampleChild c = new ExampleChild();
p.printText(13);
c.printText(18);
}
}
- KLASA "ExampleParent"
public class ExampleParent
{
public void printText(int n)
{
System.out.println("Wypisuję liczbę całkowitą: " + n);
}
}
- KLASA "ExampleChild"
public class ExampleChild extends ExampleParent
{
@Override
public void printText(int n)
{
super.printText(n);
System.out.println("A oto dalszy ciąg tekstu!");
}
}
Widzicie sami, że przeciążanie a przesłanianie robi różnicę i wcale nie wygląda tak podobnie do siebie. Pierwszy kod ukazuje kilka metod o tej samej nazwie, a drugi obrazuje "podmienianie" zawartości tej samej metody własną inną zawartością. Częstym manewrem (i zarazem bardzo użytecznym) jest przesłanianie metody "toString" (tu jest artykuł poświęcony tej metodzie).
Adnotacja "@Override" informuje kompilator, że dana funkcja jest nadpisywana (przesłaniana). Słowo kluczowe "super" ma wiele znaczeń i działa nie tylko w tym kontekście, szczegóły są prezentowane w osobnym artykule. Powiem jedynie, że jeśli sobie to zakomentujecie, to ukaże się jedynie drugi tekst niepobierający liczby z parametru. Nie tak trudno jest wywnioskować co to konkretnie robi.
Tak się sprawy mają. Zapamiętajcie sobie raz na zawsze: przeciążanie a przesłanianie to są dwie ZUPEŁNIE RÓŻNE czynności w Javie! Nie wyłóżcie się na rozmowie kwalifikacyjnej.