здрасти Вие вече използвате Java методи и знаете много за тях. Вероятно сте се сблъсквали със ситуация, в която един клас има много методи с едно и също име, но различни параметри. Спомняте си, че в тези случаи използвахме претоварване на метода. Днес разглеждаме друга ситуация. Представете си, че имаме един споделен метод, но той трябва да прави различни неща в различни класове. Как да приложим това поведение? За да разберем, нека разгледаме родителски клас Animal , който представлява животни, и ще създадем метод speak в него:
Нашата цел е проста: избягвайте създаването на много методи за говорене. Вместо да създаваме метод catSpeak() за мяукане, метод snakeSpeak() за съскане и т.н., искаме да извикаме speak()метод и накарайте змията да съска, котката да мяуче и кучето да лае. Можем лесно да постигнем това, като използваме отмяна на метода. Уикипедия дава следното обяснение на термина „замяна“: Замяната на метод в обектно-ориентираното програмиране е езикова характеристика, която позволява на подклас or дъщерен клас да предостави специфична реализация на метод, който вече е предоставен от един от неговите суперкласове or родителски класове Това по същество е правилно. Замяната на метода ви позволява да вземете няHowъв метод от родителския клас и да напишете своя собствена реализация във всеки дъщерен клас. Новата реализация „заменя“ родителската реализация в дъщерния клас. Нека да видим How изглежда това в пример. Създайте 4 класа, които наследяват нашия клас Animal :
Замяната има няколко ограничения:
public class Animal {
public void speak() {
System.out.println("Hello!");
}
}
Въпреки че току-що започнахме да пишем програмата, вероятно виждате потенциален проблем: в света има много животни и всички те „говорят“ по различен начин: котките мяучат, патиците крякат и змиите съскат. 
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!");
}
}
„Ето малък лайфхак за бъдещето: за да замените методите на родителския клас, отидете на codeа на дъщерния клас в IntelliJ IDE, щракнете върху Ctrl+O и изберете „Замени методите...“ в менюто. Свикнете с използването на горещи клавиши от самото начало — това ще ви помогне да пишете програми по-бързо!За да уточним поведението, от което се нуждаем, направихме няколко неща:
- Във всеки дъщерен клас създадохме метод със същото име като метода на родителския клас.
- Казахме на компилатора, че именуването на метода по същия начин като в родителския клас не е случайност: искаме да отменим поведението му. За да съобщим това на компилатора, задаваме анотацията @Override над метода.
Когато се постави над метод, анотацията @Override информира компилатора (Howто и програмистите, които четат вашия code): „Всичко е наред. Това не е грешка. Не забравям. Наясно съм, че такъв метод вече съществува и искам да го отменя“. - Написахме имплементацията, от която се нуждаем за всеки дъщерен клас. Когато се извика методът speak() , змия трябва да съска, мечка трябва да ръмжи и т.н.
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();
}
}
Конзолен изход:
Woof!
Meow!
Growl!
Hiss!
Отлично! Всичко работи Howто трябва! Създадохме 4 референтни променливи, които съхраняват обекти от родителския клас Animal , и им присвоихме екземпляри на 4 различни дъщерни класа. В резултат на това всеки обект проявява собствено поведение. За всеки дъщерен клас заместеният метод speak() замени „родния“ метод speak() в класа Animal (който просто показва „Здравей!“). 
-
Замененият метод трябва да има същите параметри като родителския метод.
Ако методът speak на родителския клас има параметър String , замененият метод в дъщерния клас също трябва да има параметър String . В противен случай компилаторът ще генерира грешка:
public class Animal { public void speak(String s) { System.out.println("Hello! " + s); } } public class Cat extends Animal { @Override // Error! public void speak() { System.out.println("Meow!"); } }
-
Замененият метод трябва да има същия тип връщане като родителския метод.
В противен случай ще получим грешка на компилатора:
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!"; } }
-
Модификаторът за достъп на заменения метод също трябва да бъде същият като „оригиналния“ метод:
public class Animal { public void speak() { System.out.println("Hello!"); } } public class Cat extends Animal { @Override private void speak() { // Error! System.out.println("Meow!"); } }
GO TO FULL VERSION