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 шт):

Автор решения: Falchio

В документации написано довольно кратко:

it helps to prevent errors

@Override аннотация сообщает компилятору, что элемент предназначен для переопределения элемента, объявленного в суперклассе. Хотя использование этой аннотации при переопределении метода не требуется, это помогает предотвратить ошибки. Если методу, отмеченному @Override, не удается корректно переопределить метод в одном из своих суперклассов, компилятор генерирует ошибку.
Это должно помочь избежать ошибок:

  • неверное написание имени метода
  • неверное сопоставление параметров метода

Так же это немного упрощает понимание кода.

Впрочем, быть может все эти плюсы нужны, когда пишешь на Java в каком-нибудь текстовом редакторе.
Хотя, я всё же хотел бы видеть эту аннотацию в коде, который читаю.

В языке Kotlin это уже не аннотация, а вполне себе ключевое слово override, без которого обойтись в случае переопределения функции не удастся. Думаю это более правильный дизайн языка.

→ Ссылка
Автор решения: Roman C

@Override - это маркер, который помогает компилятору найти ошибку в коде, то есть позволяет найти класс или интерфейс, в котором отсутствует переопределенный метод. Отсутствие этой аннотации не влияет на работу программы, если метод переопределен правильно.

Эта аннотация ставится как на методы классов, так и на методы интерфейсов. Привязывая тем самым интерфейс к конкретной реализации. То есть если удалить переопределенный метод из интерфейса, то компилятор сразу выдаст ошибку. Абстрактные классы и интерфейсы менять нельзя в процессе разработки.

То есть если стоит аннотация @Override, то можно с уверенностью сказать что в базовом наследуемом классе или имплементируемом интерфейсе, обязательно есть метод с одинаковой сигнатурой, который обязательно переопределен. В противном случае, если аннотация не стоит, то переопределенного метода может и не быть. То есть мы не можем точно сказать переопределяет или нет метод в родительском классе или интерфейсе.

→ Ссылка