2011-12-03 76 views
5

下面是這種情況評論一種在C#中同時覆蓋並覆蓋的方法?

 public class Connection 
    { 
     public virtual void close() 
     { 
      /*Some code */ 
     } 
    } 

    public interface IHttpRelay 
    { 

     void close(); 

    } 

    public class HttpConnection: Connection,IHttpRelay 
    { 
     public /*keyword*/ void close() 
     { 
      base.close(); 
     } 
    } 

    public class Http:HttpConnection 
    { 
     public override void close() 
     { 
      /*Some code */ 
     } 
    } 

我的問題是要知道我是否應該申報的方法的close()的HttpConnection類的覆蓋虛擬關鍵字,因爲它會覆蓋和被覆蓋與此同時。

回答

2

您需要用override來標記。如果將它標記爲virtual,HttpConnection,則將隱藏的基類實現,不覆蓋它。因此,它不能多形地使用。標記一種虛擬方法,其餘的應該簡單地覆蓋。

作爲簡單的例子

class A 
{ 
    public virtual void Frob() 
    { 
     Console.WriteLine("A"); 
    } 
} 

class B : A 
{ 
    public virtual void Frob() 
    { 
     Console.WriteLine("B"); 
    } 
} 

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

在這裏,B重新定義虛擬FROB,它不會覆蓋。它遵循你的例子。但是,通過引用A來處理C的實例時,會發生「意外」情況。

A obj = new C(); 
obj.Frob(); // "A" is written to the screen, not "C" 

什麼是寫到屏幕上的是「A」,你沒有得到你期望的多態行爲。當你隱藏一個成員而不是覆蓋成員時,你只能通過隱藏類的引用來獲得新的行爲。當通過基類引用時,您會收到基本行爲!這通常不是你想要的虛擬/覆蓋多態場景。如果在B類中將virtual替換爲override,然後運行上面的代碼片段,則輸出結果就是您所期望的。

1

您必須僅聲明override。該documentationvirtual狀態:

不能與staticabstractprivate,或者override改性劑使用virtual修改。

如果你想想看,virtual override沒有任何意義:如果不出意外,你可以不知道,如果有人將覆蓋覆蓋在將來,肯定一類的作家不能回去,並添加virtual在您決定重寫它之後修改方法。

+0

您重寫的任何方法必須已經是虛擬的,所以如果語言允許您再次向其添加「虛擬」修飾符,將會引起混淆。 – Joren

2

override修飾符不會阻止派生類再次重寫相同的方法。爲了防止這種情況,你也應該使用sealed修飾符。