В чем разница между переопределением и новыми ключевыми словами В C#?
в чем разница между override
и new
ключевые слова в C# при определении методов в иерархии классов?
5 ответов:
на следующей странице очень хорошо резюмируется ваш вопрос.
зная, когда использовать переопределение и новые ключевые слова
резюме
переопределить: когда метод базового класса переопределяется в производном классе, используется версия в производном классе, даже если вызывающий код не "знал", что объект является экземпляром производного класса.
новая: если вы используете ключевое слово new вместо переопределения метод в производном классе не переопределяет метод в базовом классе, он просто скрывает его.
Если вы не укажете ни new, ни overrides, результат будет таким же, как если бы вы указали new, но вы также получите предупреждение компилятора (поскольку вы можете не знать, что вы скрываете метод в методе базового класса, или действительно Вы, возможно, хотели его переопределить и просто забыли включить ключевое слово).
переопределить: используется виртуальные/абстрактные/переопределение метода в базовом классе
новая: когда базовый класс не объявил метод как virtual / abstract / override
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
; в лучшем случае, это сбивает с толку, потому что вы определяете метод с именем, которое может быть признано как что-то в противном случае, и в худшем случае, он может скрывать ошибки, вводить кажущиеся невозможными ошибки и затруднять расширение функциональности.
похоже, старый вопрос, Позвольте мне попробовать другой ответ:
new
: как следует из названия, это новый элемент в семействе иерархии наследования, и он будет использоваться в качестве базового элемента для дальнейшего вниз по цепочке (если он помечен как виртуальный).
override
: это означает, что я не принимаю реализацию члена моего родительского класса, и я буду делать по-другому.
рассмотрим следующую иерархию классов:
using System; namespace ConsoleApp { public static class Program { public static void Main(string[] args) { Overrider overrider = new Overrider(); Base base1 = overrider; overrider.Foo(); base1.Foo(); Hider hider = new Hider(); Base base2 = hider; hider.Foo(); base2.Foo(); } } public class Base { public virtual void Foo() { Console.WriteLine("Base => Foo"); } } public class Overrider : Base { public override void Foo() { Console.WriteLine("Overrider => Foo"); } } public class Hider : Base { public new void Foo() { Console.WriteLine("Hider => Foo"); } } }
вывод вышеуказанных кодов должен быть:
Overrider => Foo Overrider => Foo Hider => Foo Base => Foo
- подкласс
overrides
виртуальный метод, применяяoverride modifier
:- если вы хотите
hide
член сознательно, в этом случае вы можете применитьnew modifier
к члену в подклассе.The new modifier does nothing more than suppress the compiler warning that would otherwise result