В чем разница между переопределением и новыми ключевыми словами в С#?

В чем разница между ключевыми словами override и new в С# при определении методов в иерархиях классов?

Ответ 1

На следующей странице представлен ваш вопрос очень хорошо.

Знать, когда использовать переопределение и новые ключевые слова

Резюме

Переопределить. Когда метод базового класса переопределяется в производном классе, используется версия в производном классе, даже если вызывающий код не "знал", что объект был экземпляр производного класса.

Новый. Если вместо переопределения использовать новое ключевое слово, метод в производном классе не переопределяет метод в базовом классе, он просто скрывает его.

Если вы не укажете ни новых, ни переопределений, результирующий результат будет таким же, как если бы вы указали новый, но вы также получите предупреждение о компиляторе (поскольку вы, возможно, не знаете, что вы скрываете метод в метод базового класса, или вы, возможно, захотели переопределить его, и просто забыли включить ключевое слово).

Переопределить: используется с типом метода virtual/abstract/override в базовом классе

Новый: когда базовый класс не объявил метод как виртуальный/абстрактный/переопределенный

Ответ 2

new затеняет метод полностью новым методом (который может иметь или не иметь одну и ту же подпись) вместо его переопределения (в этом случае новый метод должен иметь одну и ту же подпись), что означает, что полиморфизм не будет Работа. Например, у вас есть следующие классы:

class A {
    public virtual int Hello() {
        return 1;
    }
}

class B : A {
    new public int Hello(object newParam) {
        return 2;
    }
}

class C : A {
    public override int Hello() {
        return 3;
    }
}

Если вы это сделаете:

A objectA;
B objectB = new B();
C objectC = new C();

Console.WriteLine(objectB.Hello(null)); // 2
Console.WriteLine(objectC.Hello()); // 3

objectA = objectB;

Console.WriteLine(objectA.Hello()); // 1

objectA = objectC;

Console.WriteLine(objectA.Hello()); // 3

Поскольку вы можете определить новые сигнатуры методов с помощью new, компилятор не может знать, что экземпляр A на самом деле является экземпляром B, а новый метод B должен быть доступен. new может использоваться, когда метод родительского объекта, свойство, поле или событие не объявлен с помощью virtual, а из-за отсутствия virtual компилятор не будет "искать" унаследованный метод. Однако с virtual и override он работает.

Я настоятельно рекомендую вам избегать new; в лучшем случае, это сбивает с толку, потому что вы определяете метод с именем, который может быть признан чем-то другим, а в худшем случае он может скрывать ошибки, вводить казалось бы невозможные ошибки и затруднять расширение функциональности.

Ответ 3

Похож на старый вопрос, позвольте мне попробовать другой ответ:

  • new: как сказано в названии, это новый член в семействе иерархии наследования, и это будет использоваться в качестве базового элемента для дальнейшего продвижения по цепочке (если отмечено как виртуальное).

  • override: Это означает, что я не принимаю реализацию моего родительского класса, и я буду делать по-другому.

Ответ 4

override позволяет вам переопределить виртуальный метод в базовом классе, чтобы вы могли поместить другую реализацию. new скроет не-виртуальный метод в базовом классе.