В чем смысл виртуального и переопределения?Разве C # не делает то же самое без них? - PullRequest
1 голос
/ 20 ноября 2011

Насколько я понимаю, ключевое слово virtual позволяет использовать метод базового класса, а override позволяет переопределить его в классе, который наследуется от базового класса.Моя путаница заключается в том, что я только что протестировал, не используя ключевое слово virtual в определении метода базового класса и не включая этот метод в производный класс, и я все еще был в состоянии вызвать метод базового класса (он обнаружился в intellisense и запустился),Кроме того, я знаю, что если бы я хотел новое определение метода для того же метода для моего производного класса, то я мог бы использовать новое ключевое слово ..

Возможно, мне не хватает ключевой точки, но я так понимаювот почему я запутался относительно цели виртуального и переопределения

Ответы [ 5 ]

3 голосов
/ 20 ноября 2011

Сила этих ключевых слов вступает в игру, когда вы используете полиморфизм

Я думаю, что пример помогает понять больше всего. Учтите следующее:

class Base {
  public virtual void f() { Console.WriteLine("Virtual Base"); }
}

class Override : Base {
  public override void f() { Console.WriteLine("Overridden derived"); }
}

class New : Base {
  public new void f() { Console.WriteLine("New derived"); }
}

Теперь, когда у вас есть объект фактического типа Derived, но статического типа Base, вызов f() все равно выдаст «Переопределенный производный»:

Base obj = new Override();
obj.f(); // Overridden derived

С ключевым словом new вы указываете среде выполнения прекратить поиск метода с таким именем, начиная с этого класса:

Base obj = new New();
obj.f(); // Virtual Base

В отличие от вызова f() для типа не менее New:

New obj = new New();
obj.f(); // New derived
2 голосов
/ 20 ноября 2011

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

Это ожидаемое поведение.

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

Различия между новым и переопределенным ключевым словом можно найти в MSDN здесь .

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

0 голосов
/ 20 ноября 2011

Когда вы помечаете метод как виртуальный или абстрактный, проверка типа во время выполнения используется для определения фактической реализации вызываемого метода: он проверяет «наиболее производный тип», который реализует / переопределяет виртуальный метод, и вызывает эта реализация. Простой метод не требует проверки типа во время выполнения.

Таким образом, различие между виртуальным и не виртуальным существенно влияет на семантику вашего кода, особенно для общедоступных API. Если вы видите это:

class A { void foo(); virtual void bar(); }
...
A myObject = getSomeObject();
myObject.foo();
myObject.bar();

Вы можете быть уверены, что вызванная реализация foo объявлена ​​в классе A. Это связано с тем, что для определения вызываемого метода используется только проверка типов во время компиляции. Однако конкретная реализация bar, которая вызывается, может быть реализацией в некотором подклассе A, в зависимости от типа времени выполнения myObject.

Подробнее: http://msdn.microsoft.com/en-us/library/aa645767(v=vs.71).aspx

0 голосов
/ 20 ноября 2011

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

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

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

0 голосов
/ 20 ноября 2011

Virtual позволяет переопределить метод базового класса. Вы по-прежнему можете вызывать метод без него, но не сможете переопределить метод без него.

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

Нижеприведенный фрагмент будет напечатан из B

public class A
{
  virtual void foo
  {
    Console.WriteLine("From A");
  }
}

public class B : A
{
  override void foo()
  {
   Console.WriteLine("From B");
  }
}

static void Main(string[] args) 
{
   A testA = new B();

   a.foo();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...