2015-12-06 8 views
2

Довольно смутно с правилами виртуального наследования, когда у меня есть метод, который предотвращает переопределение производного класса из виртуального метода, определенного в базовом классе. Вот немного кода, чтобы объяснить мою проблему лучше:Виртуальное наследование в C#

using System; 

namespace ConsoleApplication1 
{ 
    public class A 
    { 
     public virtual void DoWork() 
     { 
      Console.WriteLine("A.DoWork()"); 
     } 
    } 
    public class B : A 
    { 
     public override void DoWork() 
     { 
      Console.WriteLine("B.DoWork()"); 
     } 
    } 

    public class C : B 
    { 
     public sealed override void DoWork() 
     { 
      Console.WriteLine("C.DoWork()"); 
     } 
    } 

    public class D : C 
    { 
     public new void DoWork() 
     { 
      Console.WriteLine("D.DoWork()"); 
     } 
    } 

    public class MyMainClass 
    { 
     public static void Main() 
     { 
      B b = new D(); 
      b.DoWork(); 

      C c = new D(); 
      c.DoWork(); 

      A a = new D(); 
      a.DoWork(); 

      Console.WriteLine("Press any key to exit"); 
      Console.ReadKey(); 
     } 
    } 
} 

ВЫВОД

C.DoWork()
C.DoWork()
C.DoWork()
Нажмите любую клавишу для выхода

Это правда, что если переменная типа B используется для доступа к экземпляру C, так как B b = new C(); b.DoWork() приведет к в вызове реализации Cи для DoWork() поскольку С переопределяет виртуальный DoWork() из A.

Но почему это, когда переменная типа C, B, или A используется для доступа экземпляр D, как

B b = new D(); 
C c = new D(); 
A a = new D(); 

вызов DoWork() для каждого из них вызовет реализацию DoWork() для класса C?

+0

@PrestonGuillot, вероятно, не - выглядит как OP просто не понимают 'virtual' и вопрос просто случайно упомянуть' sealed'/new' ' , –

+0

Я голосую, чтобы закрыть этот вопрос как не относящийся к теме, потому что OP пытается сделать противоположный тому, на каком языке был создан –

+0

Как и http://stackoverflow.com/questions/4152049/sealed-method-in-c- sharp –

ответ

1

Класс D теперь имеет два метода: DoWork.

Первый (метод # 1) - это виртуальный метод, определенный в классе A и переопределенный в классе C. D наследует этот метод от C.

Второй (метод # 2) является не виртуальным методом, который определен в самом классе D. Этот метод полностью отличается от метода №1.

Теперь у вас нет доступа к методу №1 от переменной типа D, потому что метод # 2 hides метод # 1.

Однако вы все равно можете получить доступ к методу # 1, используя переменную типа A, B или C.

Чтобы сделать это более ясным, вот пример:

D var_d = new D(); 

B var_b = var_d; 

var_d.DoWork(); //This accesses method #2 on an object of type D 

var_b.DoWork(); //This accesses method #1 on the same object 
+0

Эй! Большое спасибо! Несколько пояснений btw ... 1) var_b - это переменная типа B, имеющая значения типа D, имеющие доступ только к переопределенному методу класса C (метод # 1), а не к переопределенным методам классов B и C (просто думая, поскольку D является подклассом C, который является подклассом B, поэтому он не наследует переопределенные методы как B, так и C?) 2) Кроме того, почему var_b интересуется только методом # 1, а не метод № 2 – mrdoubtful

+0

1) Разве вы не имеете в виду B и A? Это тот же метод (метод # 1). Но поскольку метод является виртуальным, то C изменил реализацию этого метода, переопределив его. –

+0

2) 'var_b' ничего не знает о методе # 2. Он знает только о методе # 1. Это верно, потому что метод # 2 определен в классе 'D'.Обратите внимание, что хотя метод # 1 был переопределен в классе 'D', его * определение * находится в классе' A'. Вот почему 'var_b' знает о методе # 1. –