Jesteście gotowi na następną część z tematu dziedziczenia? Podnosimy poprzeczkę i zaprezentuję Wam kolejne słowo kluczowe umożliwiające łączenie przesłaniania metody z wywoływaniem jej "wersji pierwotnej". Jest nim "super" w języku Java. Dziedziczenie to jeden z szerszych tematów który co gorsza, jest elementarną podstawą do umiejętnego wykorzystywania paradygmatu obiektowego.

"SUPER" W JĘZYKU JAVA. JEDNO SŁOWO, WIELE ZNACZEŃ

Czy kojarzycie słówko "super"? Musiało się Wam ukazać przed oczami chociaż parę razy. Jeśli skupicie swoją uwagę na tym artykule, dołączycie do grona osób rozumiejących znaczenie tego słowa. Tutaj stoimy na rozdrożu.

ODWOŁYWANIE SIĘ DO KLASY BAZOWEJ

Pierwsze znaczenie: odwoływanie się do metod i konstruktorów dotyczących klasy od której się dziedziczy. Zakładając, że są dwie klasy posiadające tę samą metodę (np. "saySomething"), jedna dziedziczy od drugiej i ta dziedzicząca od drugiej posiada przesłoniętą metodę o tej samej nazwie, to wyrażenia:

saySomething();

oraz

super.saySomething();

będą znaczyły coś innego. Pierwsze wywołanie spowoduje wykonanie instrukcji tej przesłoniętej metody, a drugie wywołanie spowoduje "powrócenie" do klasy z której się dziedziczy, wyszukanie tej samej metody i wykonanie instrukcji znajdujących się w klasie bazowej (nadrzędnej). Dziedziczenie pozwala posunąć się dalej przez co można połączyć jedno z drugim i dzięki temu wykonać parę własnych instrukcji w przesłoniętej metodzie i wykonać "pierwowzór" za jednym zamachem!

Wspomniałem też coś o konstruktorach: owszem. To również dotyczy konstruktorów i one też mają związek ze słowem "super" w języku Java. Natomiast wtedy to jest zupełnie inna postać rzeczy. Po pierwsze, konstruktor klasy bazowej musi być pierwszą instrukcją w konstruktorze klasy która ją wywołuje, a po drugie, używamy samego słowa "super" wraz z listą parametrów. Wszystko się wyjaśni jak zobaczycie poniższy kod.

PRZYKŁAD KODU ŹRÓDŁOWEGO

Podsumujmy te wiadomości w miarę zwięzłym kodem źródłowym. Możemy używać "super" w języku Java zarówno w kontekście metod, jak i konstruktorów klasy bazowej. Wystarczy tylko opanować kilka następnych zasad dotyczących składni:

KLASA "MAIN"
public class Main
{
	public static void main(String[] args)
	{
		Warrior w = new Warrior();

		w.setLevel(86);
	}
}
KLASA "CHARACTER"
public abstract class Character
{
	private int level;

	public Character(int level)
	{
		System.out.println("Wywołuję konstruktor klasy \"Character\".");
		setLevel(level);
	}

	public void setLevel(int level)
	{
		this.level = level;
	}
}
KLASA "WARRIOR"
public class Warrior extends Character
{
	public Warrior()
	{
		super(1);
		System.out.println("Wywołuję konstruktor klasy \"Warrior\".");
	}

	@Override
	public void setLevel(int level)
	{
		super.setLevel(level);
		System.out.println("\"Warrior\" teraz ma poziom " + level + ".");
	}
}

Funkcja "setLevel" domyślnie tylko nadpisuje daną składową. Aby nie tracić znaczenia nazwy metody, przesłanianie odwołuje się do klasy bazowej, wykonuje instrukcje, a następnie wraca i dodaje nowe polecenia, w tym przypadku komunikat. Dodam, że jeśli w klasie "Character" zamienicie metodę "setLevel" na zwykłe przypisanie wartości do zmiennej "level", to wówczas zobaczycie tylko jeden tekst zamiast dwóch. Wiecie już dlaczego?

Przy okazji zwróćcie uwagę na kolejność wykonywania konstruktorów oraz na fakt, że klasa abstrakcyjna TAKŻE ma prawo mieć konstruktor. Tak na marginesie jeszcze dopiszę, że ten "łańcuch" wywołań nie kończy się na naszej klasie "najbardziej ogólnej", tylko na "ukrytej" klasie "Object", "matce" wszystkich obiektów. W chwili tworzenia własnej klasy, wykonywane jest niejawne rozszerzanie o klasę "Object", tak samo jakbyśmy dopisali "extends Object" (jeśli nie rozszerzamy jawnie o inną klasę).

KOWARIANCJA

Drugie znaczenie: kowariancja typu generycznego. A że dotyczy to typów generycznych, zachęcam do poczytania o teorii stosowania typów generycznych. Mogliście zobaczyć słowo "super" w języku Java wewnątrz nawiasów kątowych. Coś takiego jak to:

ArrayList ? super Integer> list = new ArrayList<Object>();

Uwaga! Brak nawiasu kątowego celowy, bo powstawał problem podczas próby zapisu.

Znak zapytania określany jest pod hasłem "wildcard", czyli "znak wieloznaczny" w znaczeniu dosłownym. Zapis wstawiony powyżej oznaczać będzie możliwość wstawienia typu klasy pochodnej w miejsce typu klasy bazowej. Więcej informacji na ten temat znajduje się w dokumentacji.

Słowo kluczowe "super" w języku Java

"super" w języku Java umożliwia sięgnięcie "wstecz" do klasy nadrzędnej i wywołanie tamtejszych metod lub konstruktorów. Słowo kluczowe można też znaleźć podczas definiowania kowariancji dla typów generycznych.


Jest już trochę trudniej, prawda? Zbliżamy się do końca tego długiego wątku, tutaj znajduje się dalszy ciąg zabaw w dziedziczenie!

PODOBNE ARTYKUŁY