использования виртуальных и новых

Насколько я вижу в С#,

виртуальные функции предназначены не только для полиморфизма,

это также для переопределения предупреждения метода скрытия компилятором

я прав ?

я приведу пример:

class A
{
   public void func(int a)
     {
        ....
     }
}
class B:A
{
   public void func(int a)
     {
        ....
     }
}

теперь я использую B x = new B();, поэтому компилятор предупредит меня о том, что метод в классе B скрывает метод в A. Таким образом, есть 2 решения:

1) пометьте тот, что в B, ключевым словом New

2) сделать один в 'A' virtual и один в B - Overriding - это снимет предупреждение о сокрытии..

единственная разница будет с полиморфизмом A x = new B();

если в классе B будет 'new' - всегда будет вызываться тот из A, а если я использую virtual и не новый механизм - будет вызываться тот из B называться.

поэтому виртуальный имеет 2 роли в .net: (пожалуйста, исправьте меня, если я ошибаюсь)

1) устранить предупреждение о сокрытии (в среде без полиморфизма)

2) и, конечно же, переопределение функций в среде yes-polymorphism.

пожалуйста, поправьте меня, если я ошибаюсь.


person Royi Namir    schedule 24.07.2011    source источник
comment
Как вы думаете, почему это как-то связано с ASP.NET?   -  person Jon Skeet    schedule 24.07.2011
comment
Вы должны узнать разницу между перегрузкой и переопределением   -  person CodesInChaos    schedule 24.07.2011
comment
Я знаю, просто я печатал очень быстро и не обращал внимания.   -  person Royi Namir    schedule 24.07.2011


Ответы (3)


Нет, виртуальные методы предназначены для полиморфизма. Ваше «решение» № 2 изменит поведение вызова x.func() с вызова реализации A на вызов реализации B, то есть сделает его полиморфным. Да, это удаляет предупреждение, но это больше не «среда без полиморфизма», поскольку вы сделали поведение полиморфным. Вы хотели это сделать или нет? Если вы это сделали, то virtual и override - это путь. Если вы этого не сделали, вы должны использовать new или переименовать метод.

Я бы настоятельно посоветовал бы вам избегать использования скрытия методов, если вам это действительно не нужно. Вам вообще нужно, чтобы B производилось от A? Если вы хотите дать ему другой метод с тем же именем, но с другим значением, подумайте о том, чтобы сделать их отдельными классами. Лично я избегаю наследования, если нет явных полиморфных отношений.

(Кстати, обратите внимание, что переопределение и перегрузка — это разные понятия. Здесь вы имеете в виду переопределение.)

person Jon Skeet    schedule 24.07.2011
comment
если я использую виртуальную и перегрузку и выполняю: B x = new B() - я не использовал никакой полиморфной команды, такой как A = new B() - и все еще скрываю предупреждение... - person Royi Namir; 24.07.2011
comment
@ Mid787: переопределить, а не перегружать. Но вы все же добавили в него полиморфизм... любой, кто напишет A x = new B();, увидит это полиморфное поведение. Что касается классов A и B, то это полиморфный вызов. Если вам не нужен полиморфизм, либо удалите отношение наследования, либо переименуйте метод. - person Jon Skeet; 24.07.2011

Предупреждение компилятора как раз об этом. Это предупреждение о том, что ваша реализация func() вероятно неверна, потому что она скрывает член от базового класса.

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

person Steve Morgan    schedule 24.07.2011

В основном ключевое слово «Новое» используется для преодоления предупреждения о методе сокрытия. в то время как виртуальное ключевое слово предназначено исключительно для полиморфизма, оно сообщает компилятору, если переопределить доступную версию метода, а затем запустить этот метод, иначе запустить виртуальный метод.

Виртуальное переопределение также называется полиморфизмом во время выполнения, потому что оно решает во время выполнения, какой метод будет запущен.

В то время как ключевое слово «Новое» удаляет предупреждение и запускает только метод дочернего класса и скрывает родительский метод, поэтому для преодоления этого мы используем:

   public new void Method()
{
//Some code
Base.Method();

}

с помощью этого мы запускаем родительский метод и показываем метод родительского класса

person SMK    schedule 24.07.2011
comment
если я использую виртуальную и перегрузку и выполняю: B x = new B() - я не использовал никакой полиморфной команды, такой как A = new B() - и все еще скрываю предупреждение... - person Royi Namir; 24.07.2011
comment
да, конечно, потому что компилятор понимает, что в этом синтаксисе ничего не скрыть. Простыми словами. Единственное место, где вам нужно использовать new, - это когда метод никак не связан с версией базового класса. Эта хорошая ссылка для чтения blog.colinmackay.net/archive/2008/10/10/4264.aspx - person SMK; 24.07.2011