2012-10-12 19 views
5

我已經瞭解到,虛擬方法的使用爲方法/函數提供了默認行爲。我的查詢是,當我們可以在派生類中使用「new」實現一個名稱相同的方法(和基類中的方法相同),並且可以分別使用對象調用它時,那麼虛擬方法的用法是什麼。例如;使用虛擬方法只有單實例生成的優勢?

class A 
{ 
     public void F() 
     { 
     //default behavior 
     } 

     public virtual void G() 
     { 
     //default behavior 
     } 
} 

class B:A 
{ 
    new public void F() 
    { 
     //new behavior from that of class A 
    } 
    public override void G() 
    { 
     //new behavior from that of class A 
    } 
} 

class Test 
{ 
    public static void Main(string[] args) 
    { 
     //For calling A's method use same compile time and run time object 
     A obj1 = new A(); 

     //For calling B's method use compile time object of A and run time of B 
     A obj2 = new B(); 

     obj1.F(); //O/P is A's method result 
     obj2.F(); //O/P is A's method result 
     obj1.G(); //O/P is A's method result 
     obj2.G(); //O/P is B's method result 
} 

我的問題是爲什麼需要虛擬G()在A類時,我們可以通過使用相同的編譯時對象提供默認行爲以及衍生行爲和運行兩個類A的時間對象和B作爲這樣的:

A obj1 = new A(); //for calling A's methods 
B obj2 = new B(); //for calling B's methods 
A obj3 = new B(); //for having default behavior of class A using B's run time object. 

我提取的只是在虛擬情況下,我們不需要再製作一個具有相同編譯和運行時類型的對象。它可以通過A類編譯時間和B類運行時間的單個對象來實現。

回答

6

我的問題是爲什麼我們可以使用相同的方法提供默認行爲時需要類A中的虛擬G()編譯時間和使用編譯時間目標運行時對象和派生的行爲和運行B.

時間

因爲這樣你可以這已經知道B只有使用的代碼。多態性的一半是允許您編寫不關心它實際與哪個子類一起工作的代碼。

例如,我可以編寫一種方法,使用Stream.ReadStream.Write將一個流的內容複製到另一個流中,這正是因爲它們是虛擬或抽象方法。不要緊,哪個實現通過。

你應該很少使用new作爲方法修飾符 - 如果你真的想爲非虛擬方法提供不同的行爲,如果你創建一個完全不同的方法方法名,這樣任何閱讀代碼的人都能理解這是一個與基類中聲明的方法非常分離的方法。

+0

也許我的想法沒有通過回覆來解決......我無法清楚地理解它。你能否給它更逼真的感覺,謝謝你的及時答覆。 – user1740176

+0

恐怕我不知道你的意思是「更逼真的接觸」。 –

+0

對不起,不太清楚。我試圖問:使用虛擬方法是否僅僅節省內存?那麼爲什麼不創建更多的對象或它有不同的原因?通過逼真的觸摸,我的意思是任何真實的生活例子 – user1740176

0

Jon指出另一個原因是,如果隱藏了使用new的實現,那麼對基類中的方法的任何引用都是針對基本實現,而如果在基類中重寫任何調用,則使用覆蓋方法

protected virtual void Foo(){ 
} 

private void Bar() { 
    //do generic stuff 
    Foo(); 
} 

如果一個類重寫foo,那麼這將改變調用bar的效果。這是某些設計模式的基礎,例如AbstractTemplate

+0

感謝您的回覆符文。道歉,無法得到你的榜樣。 – user1740176

相關問題