В чем разница между ключевыми словами 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
скроет не-виртуальный метод в базовом классе.