2015-10-05 83 views
2
class MyBaseClass 
{ 
    virtual public void Print() 
    { 
     Console.WriteLine("This is the base class."); 
    } 
} 

class MyDerivedClass : MyBaseClass 
{ 
    override public void Print() 
    { 
    Console.WriteLine("This is the derived class."); 
    } 
} 

class Program 
    { 
    static void Main() 
    { 
     MyDerivedClass derived = new MyDerivedClass(); 
     MyBaseClass mybc = (MyBaseClass)derived; 

     derived.Print(); 
     mybc.Print(); 

    } 
    } 

OUTPUT:派生類沒有調用基類的方法

This is the derived class. 
This is the derived class. 

我不明白爲什麼派生類的print()方法第二個電話打印,因爲我投mybc對象的基類。我期望它可以打印基類打印方法。我在這裏錯過了什麼嗎?

+0

退房在本網站經過深思熟慮的討論類似被問到的問題:http://stackoverflow.com/questions/1334254/how-can-i-call-the-base-implementation-of-an-被覆蓋的虛擬方法 –

+0

刪除覆蓋關鍵字,所有將工作正常 – 2015-10-05 08:40:29

+0

@PranavPatel它將工作在技術意義上,但通常這將是一個糟糕的設計。 –

回答

4

變量類型和實例類型是兩種不同的類型。 Casting不會更改實例類型。

當你聲明一個方法是虛擬/抽象時,你說你想要實例類型來確定被調用時的行爲。

另請注意,此賦值是有效的 - 不需要使用轉換語法將變量類型從子類更改爲基類。這種演員可以隱式完成。

MyBaseClass mybc = derived; 
+0

注意c#轉換語法,有時會轉換並有時轉換。 –

+0

當我將派生對象轉換爲基礎對象時,就像在上面的代碼中那樣,是否更改對象類型?例如,在這段代碼中,mybc變成了MyBaseClass對象,還是隻是一個指向派生對象的指針? MyBaseClass mybc =(MyBaseClass)派生; – Lyrk

+0

你沒有。你說:「使用這個Shape變量來引用我的Square」,但它仍然是一個Square。 –

2

覆蓋虛擬方法的重點在於調用對象的底層(運行時)類型的版本,而不是靜態(編譯時)類型的版本 - 即使通過類型調用它時聲明爲基類。

所以這是表現完全一樣。

如果不是這種情況,它會使類層次結構的很多實用工具無用,因爲您無法通過傳遞給定製派生類來更改傳遞給方法的類類型的行爲。

3

您已覆蓋它。它只調用派生的方法。您必須明確call the base class' method

override public void Print() { 
    base.Print(); 
    Console.WriteLine("This is the derived class."); 
} 
+0

當然,您只能從覆蓋類中調用基本版本。你不能從課堂外調用基礎版本。 –

相關問題