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ść!

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 funkcji 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 funkcji 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, zatem 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.

PODOBNE ARTYKUŁY