Override бесполезен?
В этом коде:
public class Main {
public static void main (String[] args){
Animal dog = new Dog();
Animal cat = new Cat();
dog.voice();
cat.voice();
}
}
public class Animal {
protected void voice(){
System.out.println("*sound*");
}
}
class Dog extends Animal {
@Override
protected void voice() {
System.out.println("Woof!");
}
}
public class Cat extends Animal{
protected void voice(){
System.out.println("Meow!");
}
}
В классе Dog
есть @Override
, в классе Cat
его нет, однако код работает корректно. В чём тогда смысл @Override
?
Ответы (2 шт):
В документации написано довольно кратко:
it helps to prevent errors
@Override
аннотация сообщает компилятору, что элемент предназначен для переопределения элемента, объявленного в суперклассе. Хотя использование этой аннотации при переопределении метода не требуется, это помогает предотвратить ошибки. Если методу, отмеченному @Override
, не удается корректно переопределить метод в одном из своих суперклассов, компилятор генерирует ошибку.
Это должно помочь избежать ошибок:
- неверное написание имени метода
- неверное сопоставление параметров метода
Так же это немного упрощает понимание кода.
Впрочем, быть может все эти плюсы нужны, когда пишешь на Java в каком-нибудь текстовом редакторе.
Хотя, я всё же хотел бы видеть эту аннотацию в коде, который читаю.
В языке Kotlin
это уже не аннотация, а вполне себе ключевое слово override
, без которого обойтись в случае переопределения функции не удастся. Думаю это более правильный дизайн языка.
@Override
- это маркер, который помогает компилятору найти ошибку в коде, то есть позволяет найти класс или интерфейс, в котором отсутствует переопределенный метод. Отсутствие этой аннотации не влияет на работу программы, если метод переопределен правильно.
Эта аннотация ставится как на методы классов, так и на методы интерфейсов. Привязывая тем самым интерфейс к конкретной реализации. То есть если удалить переопределенный метод из интерфейса, то компилятор сразу выдаст ошибку. Абстрактные классы и интерфейсы менять нельзя в процессе разработки.
То есть если стоит аннотация @Override
, то можно с уверенностью сказать что в базовом наследуемом классе или имплементируемом интерфейсе, обязательно есть метод с одинаковой сигнатурой, который обязательно переопределен. В противном случае, если аннотация не стоит, то переопределенного метода может и не быть. То есть мы не можем точно сказать переопределяет или нет метод в родительском классе или интерфейсе.