2016-01-07 69 views
1

我正在讀這篇文章 Overriding vs method hiding虛擬關鍵字是否調用大多數派生方法的定義?

我讀到「..When虛擬方法被調用的對象上,則該方法最派生版本被稱爲

但是,當我執行以下代碼:

class A 
     { 
      public virtual void print() 
      { 
       Console.WriteLine("A called"); 
       Console.Read(); 
      } 

     } 

     class B :A 
     { 
      public override void print() 
      { 
       Console.WriteLine("B called"); 
       Console.Read(); 
      } 
     } 
     class C : B 
     { 
      public override void print() 
      { 
       Console.WriteLine("C called"); 
       Console.Read(); 
      } 
     } 
     static void Main(string[] args) 
     { 
      B b = new B(); 
      b.print(); it prints B? 

     } 

它打印B。如果上面引用的陳述是真的,它不應該是「C」嗎? 我錯過了什麼?在這種情況下,「多數派生」是什麼意思?

+0

實際實例的派生最多被稱爲 - 如果您實例化B,則會打印B。試試'A a = new B(); a.print();'或'A a = new C(); a.print();' – Marwie

+0

@Marwie它會打印A – Arbaaz

+0

不,它會打印B或C.嘗試一下。 – Marwie

回答

1

它會調用從哪個實例調用它的類型的方法,使用的是B類的實例是,打電話如果你使用類C然後重寫實現C類的實例,以便執行B將被調用會被調用。

例如:

class B :A 
     { 
      public override void print() 
      { 
       Console.WriteLine("B called"); 
       Console.Read(); 
      } 
      public virtual void printfromB() 
      { 
       Console.WriteLine("printfromB in B called"); 
       Console.Read(); 
      } 
     } 
     class C : B 
     { 
      public override void print() 
      { 
       Console.WriteLine("C called"); 
       Console.Read(); 
      } 

      public override void printfromB() 
      { 
       Console.WriteLine("printfromB in C called"); 
       Console.Read(); 
      } 
     } 

現在如果你調用它像:

static void Main(string[] args) 
    { 
     A a = new C(); 
     a.print(); // it prints C (most derived implementation called) 
     B b = new C(); 
     b.printfromB(); // it prints "printfromB in C called" 

    } 
+0

但爲什麼使用「最衍生」版本作者可能只是說「派生」版本。還有更多嗎? – Arbaaz

+0

作者可能會這樣說,如果你創建了大多數派生的實例,那麼覆蓋大多數派生的實現將被調用。 –

+0

@Arbaaz你重寫了兩次相同的方法。因此,如果您執行Ehsan Sajjad示例中的'a.print()',則會執行該方法的最派生版本。在C實例的情況下,C的'print'方法將會贏 - 即使C是從已經實現了'print'的B派生出來的。 – Marwie

0

有沒有辦法,C將永遠是當實際類型是B調用。

原來的「最終派生」一詞可以用理解以下幾點:

A data = new C(); 
data.print(); 

即使編譯器將dataA,該最衍生(不A.printB.printC.print)版本將被調用(這是因爲該方法是virtual)。

Polymorphism

0

我認爲你正在使用的答案的話技術性混淆。

這裏有兩件事情,

  1. 大多數衍生派生類的上下文中的方法的版本中實例化。

所以,如果你這樣做,

  A a = new B(); 
      a. print(); // this will invoke the method on the class B, 
         // since instance of class A has reference to instance of B. 

,如果你做到以下幾點:

  A a = new C(); 
      a. print(); // Should call the method on class C, since base class has reference to to the instance of C. 

同樣地,把它更直觀的方法是:

  A a = new A(); 
      a.print(); // this will call the method print in class A irrespective of whether this method was overriden in one of the derived classes. 

這是動態多態的前提,其中客戶可以調用方法在A 的基類對象上打印()而不需要知道A是否引用B或C.該行爲在客戶端代碼中動態更改。

  • 或者,也可以考慮以如下方式最衍生版本:
  • 假設方法打印(c)中沒有被重寫,但在被重寫B, 那麼print()的派生版本將會在B類中。下面的代碼片段應該會有所幫助。

      class A 
          { 
           public virtual void print() 
           { 
            Console.WriteLine("A called"); 
            Console.Read(); 
           } 
          } 
          class B :A 
          { 
           public override void print() 
           { 
            Console.WriteLine("B called"); 
            Console.Read(); 
           } 
          } 
          class C : B 
          { 
           public void somerandommethod() 
           { 
            // some random method not really relevant to this example. 
           } 
          } 
    
          static void Main(string[] args) 
          { 
           A a = new C(); 
           a.print(); // it will now print B (since B has the most derived implementation of print()) 
    
          } 
    

    希望此回答有幫助。

    最好。

    相關問題