В чем различия между объявлением метода в базовом типе " virtual
" и последующим переопределением его в дочернем типе с помощью override
ключевого слова " " по сравнению с простым использованием new
ключевого слова " " при объявлении метода сопоставления в дочернем типе?
c#
syntax
overriding
method-hiding
member-hiding
i3ensays
источник
источник
new
создает новый элемент с тем же именем и приводит к тому, что исходный элемент становится скрытым, в то же времяoverride
расширяется реализация для унаследованного элемента»Ответы:
Ключевое слово «new» не переопределяет, оно означает новый метод, который не имеет ничего общего с методом базового класса.
Это печатает false, если вы использовали переопределение, это напечатало бы true.
(Базовый код взят у Джозефа Дейгла)
Так что, если вы делаете настоящий полиморфизм, вы ДОЛЖНЫ ВСЕГДА ПЕРЕПИСАТЬ . Единственное место, где вам нужно использовать «new», - это когда метод никак не связан с версией базового класса.
источник
virtual
в основе иoverride
в производной? Почему это существует? Код по-прежнему будет работать даже без кодаnew
- так это просто читабельность?Я всегда нахожу такие вещи легче понять с помощью картинок:
Снова, принимая код Джозефа Дейгла,
Если вы затем вызываете код следующим образом:
ПРИМЕЧАНИЕ. Важно то, что наш объект на самом деле является объектом
Bar
, но мы храним его в переменной типаFoo
(это похоже на приведение)Тогда результат будет следующим, в зависимости от того, использовали ли вы
virtual
/override
илиnew
когда объявляли свои классы.источник
Вот некоторый код, чтобы понять разницу в поведении виртуальных и не виртуальных методов:
источник
new
чтобы «скрыть» базовый метод, когда просто не используется переопределение, кажется, делает то же самое?virtual
и компилятор будет жаловаться, если он увидит то же имя функции в классе «bloodline» безvirtual
подписиnew
Ключевое слово на самом деле создает совершенно новый элемент , который существует только на этом типе конкретного.Например
Метод существует на обоих типах. Когда вы используете отражение и получаете члены типа
Bar
, вы на самом деле найдете 2 вызываемых метода,DoSomething()
которые выглядят абсолютно одинаково. Используя его,new
вы эффективно скрываете реализацию в базовом классе, так что когда классы являются производнымиBar
(в моем примере), вызов методаbase.DoSomething()
идетBar
и не выполняетсяFoo
.источник
virtual / override сообщает компилятору, что оба метода связаны, и что в некоторых случаях, когда вы думаете, что вызываете первый (виртуальный) метод, на самом деле правильно вместо этого вызывать второй (переопределенный) метод. Это основа полиморфизма.
Вызовет переопределенный метод VirtualFoo () подкласса.
new сообщает компилятору, что вы добавляете метод в производный класс с тем же именем, что и метод в базовом классе, но они не имеют никакого отношения друг к другу.
Вызовет метод NewBar () BaseClass, тогда как:
Вызовет метод NewBar () подкласса.
источник
Помимо технических деталей, я думаю, что использование virtual / override передает много семантической информации о дизайне. Когда вы объявляете метод виртуальным, вы указываете, что ожидаете, что реализующие классы могут захотеть предоставить свои собственные реализации, отличные от заданных по умолчанию. Опуская это в базовом классе, также объявляем ожидание, что метод по умолчанию должен быть достаточным для всех реализующих классов. Точно так же можно использовать абстрактные объявления, чтобы заставить реализующие классы предоставлять свою собственную реализацию. Опять же, я думаю, что это многое говорит о том, как программист ожидает, что код будет использоваться. Если бы я писал как базовый, так и реализующий классы и обнаружил, что использую новый, я бы серьезно переосмыслил решение не делать метод виртуальным в родительском и специально объявил о своем намерении.
источник
Разница между ключевым словом override и новым ключевым словом заключается в том, что первый выполняет переопределение метода, а второй - скрытие метода.
Проверьте следующие ссылки для получения дополнительной информации ...
MSDN и другие
источник
new
Ключевое слово для сокрытия. - означает, что вы прячете свой метод во время выполнения. Вывод будет основан на методе базового класса.override
для переопределения. - означает, что вы вызываете свой метод производного класса со ссылкой на базовый класс. Вывод будет основан на методе производного класса.источник
Моя версия объяснения исходит из использования свойств, чтобы помочь понять различия.
override
достаточно просто, верно? Базовый тип переопределяет родительский.new
возможно, вводит в заблуждение (для меня это было). Со свойствами это легче понять:Используя отладчик, вы можете заметить, что он
Foo foo
имеет 2GetSomething
свойства, так как на самом деле он имеет 2 версии свойства,Foo
s иBar
s, и узнать, какое из них использовать, c # «выбирает» свойство для текущего типа.Если бы вы хотели использовать версию Bar, вы бы использовали
Foo foo
вместо нее override или use .Bar bar
имеет только 1 , так как он хочет полностью нового поведения дляGetSomething
.источник
Не помечать метод чем-либо означает: Привязать этот метод, используя тип компиляции объекта, а не тип времени выполнения (статическое связывание).
Маркировка метода с
virtual
помощью средства: привязать этот метод, используя тип времени выполнения объекта, а не тип времени компиляции (динамическое связывание).Маркировка
virtual
метода базового классаoverride
в производном классе означает: это метод, который должен быть связан с использованием типа времени выполнения объекта (динамическое связывание).Маркировка
virtual
метода базового класса с помощьюnew
в производном классе означает: Это новый метод, который не имеет отношения к методу с тем же именем в базовом классе, и его следует связать с использованием типа времени компиляции объекта (статическая привязка).Отсутствие пометки
virtual
метода базового класса в производном классе означает: этот метод помечен какnew
(статическая привязка).Маркировка метода
abstract
означает: этот метод является виртуальным, но я не буду объявлять тело для него, а его класс также является абстрактным (динамическое связывание).источник