
Animal
oznaczającą zwierzęta i stwórzmy w niej metodę
speak
- „
głos ”:
public class Animal {
public void speak() {
System.out.println("Hello!");
}
}
Chociaż dopiero zaczęliśmy pisać program, potencjalny problem najprawdopodobniej jest już dla Ciebie widoczny: zwierząt na świecie jest bardzo dużo i wszystkie „mówią” inaczej: koty miauczą, kaczki kwaczą, węże syczą.

meow()
miauczenia,
hiss()
syczenia itp., chcemy, aby
speak()
wąż syczał, kot miauczał, a pies szczekał, gdy metoda zostanie wywołana. Możemy to łatwo osiągnąć za pomocą
mechanizmu nadpisywania metody (Override w Javie) . Wikipedia podaje wyjaśnienie terminu „przesłanianie”
:
Przesłanianie metody
) w programowaniu obiektowym, jedna z cech języka programowania, która pozwala podklasie lub klasie potomnej na zapewnienie określonej implementacji metody już zaimplementowanej w jednej z nadklas lub klas nadrzędnych. Generalnie jest to poprawne. Przesłanianie pozwala ci wziąć jakąś metodę klasy nadrzędnej i napisać własną implementację tej metody w każdej klasie pochodnej. Nowa implementacja „zastąpi” rodzica w klasie potomnej. Zobaczmy jak to wygląda na przykładzie. Stwórzmy 4 klasy potomne dla naszej klasy
Animal
:
public class Bear extends Animal {
@Override
public void speak() {
System.out.println("Growl!");
}
}
public class Cat extends Animal {
@Override
public void speak() {
System.out.println("Meow!");
}
}
public class Dog extends Animal {
@Override
public void speak() {
System.out.println("Woof!");
}
}
public class Snake extends Animal {
@Override
public void speak() {
System.out.println("Hiss!");
}
}
Mały hack na przyszłość: aby nadpisać metody klasy nadrzędnej, przejdź do kodu klasy pochodnej w
Intellij IDE a, naciśnij
Ctrl+O i wybierz z menu „
Zastąp metody… ”. Przyzwyczaj się od początku do używania skrótów klawiszowych, przyspiesza to pisanie programów! Aby ustawić pożądane zachowanie, wykonaliśmy kilka czynności:
- Stworzyliśmy metodę w każdej klasie potomnej o tej samej nazwie, co metoda w klasie nadrzędnej.
-
Powiedzieliśmy kompilatorowi, że nie tylko wywołaliśmy tę metodę tak samo, jak w klasie nadrzędnej: chcemy nadpisać jej zachowanie. W przypadku tej „wiadomości” do kompilatora umieszczamy adnotację @Override („przesłonięta”) nad metodą.
Adnotacja @Override nad metodą mówi kompilatorowi (a także programistom, którzy czytają twój kod): „W porządku, to nie jest błąd ani moje zapomnienie. Pamiętam, że istnieje już taka metoda i chcę ją zastąpić. - Napisaliśmy implementację, której potrzebujemy dla każdej klasy potomnej. Wąż powinien syczeć na wezwanie
speak()
, niedźwiedź warczeć itp.
public class Main {
public static void main(String[] args) {
Animal animal1 = new Dog();
Animal animal2 = new Cat();
Animal animal3 = new Bear();
Animal animal4 = new Snake();
animal1.speak();
animal2.speak();
animal3.speak();
animal4.speak();
}
}
Wyjście konsoli:
Woof!
Meow!
Growl!
Hiss!
Super, wszystko działa jak należy! Stworzyliśmy 4 zmienne referencyjne klasy nadrzędnej
Animal
i przypisaliśmy je do 4 różnych obiektów klas potomnych. W rezultacie każdy obiekt zachowuje się inaczej. Dla każdej z klas pochodnych nadpisana metoda
speak()
zastąpiła metodę „natywną”
speak()
z klasy
Animal
(która wypisuje tylko „Głos!” na konsoli).

-
Metoda nadpisana musi mieć takie same argumenty jak metoda nadrzędna.
Jeśli
speak
metoda klasy nadrzędnej akceptuje jako inputString
, zastąpiona metoda w klasie potomnej musi również akceptować jako inputString
, w przeciwnym razie kompilator zgłosi błąd:public class Animal { public void speak(String s) { System.out.println("Speaking: " + s); } } public class Cat extends Animal { @Override // Error! public void speak() { System.out.println("Meow!"); } }
-
Zastąpiona metoda musi mieć ten sam zwracany typ co metoda nadrzędna.
W przeciwnym razie otrzymamy błąd kompilacji:
public class Animal { public void speak() { System.out.println("Hello!"); } } public class Cat extends Animal { @Override public String speak() { // Error! System.out.println("Meow!"); return "Meow!"; } }
-
Modyfikator dostępu przesłoniętej metody również nie może różnić się od „oryginalnego”:
public class Animal { public void speak() { System.out.println("Hello!"); } } public class Cat extends Animal { @Override private void speak() { // Error! System.out.println("Meow!"); } }
speak()
dla wszystkich zamiast wielu metod itp
bark()
.
meow()
GO TO FULL VERSION