2016-06-21 2 views
0

У меня есть пример кода в C#Out-линии для виртуального метода в C#

using System; 
class A 
{ 
    public virtual void F() { Console.WriteLine("A.F"); } 
} 
class B: A 
{ 
    public override void F() { Console.WriteLine("B.F"); } 
} 
class C: B 
{ 
    new public virtual void F() { Console.WriteLine("C.F"); } 
} 
class D: C 
{ 
    public override void F() { Console.WriteLine("D.F"); } 
} 
class Test 
{ 
static void Main() { 
    D d = new D(); 
    A a = d; 
    B b = d; 
    C c = d; 
    a.F(); 
    b.F(); 
    c.F(); 
    d.F(); 
} 
} 

Этот код очертание

B.F 
B.F 
D.F 
D.F 

Я не понимаю, почему в случае a.F(); Есть B.F?

как MS сказал, что виртуальные методы в represended по типу объекта в реальном масштабе времени

ответ

1

Я не понимаю, почему в случае a.F(); Есть B.F?

MSDN #

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

Жирное содержание будет объяснить вам, почему B.F печатаются при A.F() называется.

1

Вызов метода F() из объекта унаследованного класса печатает B.F для объекта типа D, отбрасываемого по типу A, поскольку вы переопределяете метод в классе B (и классе D).

Ваш тест является почти точной копией примера, приведенного в this MSDN post on virtual methods:

using System; 
class A 
{ 
    public void F() { Console.WriteLine("A.F"); } 
    public virtual void G() { Console.WriteLine("A.G"); } 
} 
class B: A 
{ 
    new public void F() { Console.WriteLine("B.F"); } 
    public override void G() { Console.WriteLine("B.G"); } 
} 
class Test 
{ 
    static void Main() { 
     B b = new B(); 
     A a = b; 
     a.F(); 
     b.F(); 
     a.G(); 
     b.G(); 
    } 
} 

В примере, А представляет невиртуальный метод F и виртуальный метод G. Класс B ПРЕДСТАВЛЯЕТ новый невиртуальном метод F, таким образом, скрывает унаследованный F, а также переопределяет наследуемый метод Г. пример производит вывод:

AF
BF
BG
BG

Обратите внимание, что заявление аО() вызывает BG, не AG Это происходит потому, что тип во время выполнения экземпляра (что B), а не тип времени компиляции из экземпляр (который является A), определяет фактическую реализацию метода для вызова. Поскольку методам разрешено скрывать унаследованные методы, возможно, что для класса содержит несколько виртуальных методов с той же подписью . Это не представляет проблемы двусмысленности, так как все, кроме , наиболее производный метод скрыты. В примере

1

В случае автофокусировка() есть Б.Ф., потому что виртуальная пустота F в классе А в В. Переопределение

Это не переопределить с помощью C, потому что есть новый оператор, который не делает переопределить метод виртуальной базы.

Так что, если есть экземпляр типа D, введенный в A, и вы вызываете F(), вызывается виртуальный метод из класса A, но учитывается последнее переопределение. Это B.F.