2009-06-16 32 views
2

我正在從PHP轉向C#。什麼是抽象的新/虛擬/覆蓋/抽象關鍵字的一些真實世界的例子?

在PHP是簡單和直接使用抽象類來創建一個「級聯倍率」圖案,基本上「基類方法將照顧它,除非該繼承類的具有相同簽名方法」。

在C#中,但我只花了大約20分鐘試圖走出關鍵字的各種組合虛擬摘要,並覆蓋基地繼承班,直到我終於得到了這個簡單的級聯覆蓋模式的正確組合。

因此,即使那些下面的代碼按我想要的方式工作,這些添加的關鍵字暗示C#可以在抽象類中做更多的事情。我查閱了這些關鍵字的例子,並且基本理解他們做了什麼,但是仍然無法想象一個真正的場景,我將使用它們而不是這個簡單的「級聯覆蓋」模式。 什麼是真實世界您在日常編程中實現這些關鍵字的方法?

代碼的工作原理:

using System; 

namespace TestOverride23433 
{ 
    public class Program 
    { 
     static void Main(string[] args) 
     { 
      string[] dataTypeIdCodes = { "line", "wn" }; 
      for (int index = 0; index < dataTypeIdCodes.Length; index++) 
      { 
       DataType dataType = DataType.Create(dataTypeIdCodes[index]); 
       Console.WriteLine(dataType.GetBuildItemBlock()); 
      } 

      Console.ReadLine(); 
     } 
    } 

    public abstract class DataType 
    { 
     public static DataType Create(string dataTypeIdCode) 
     { 
      switch (dataTypeIdCode) 
      { 
       case "line": 
        return new DataTypeLine(); 
       case "wn": 
        return new DataTypeWholeNumber(); 
       default: 
        return null; 
      } 
     } 

     //must be defined as virtual 
     public virtual string GetBuildItemBlock() 
     { 
      return "GetBuildItemBlock executed in the default datatype class"; 
     } 
    } 

    public class DataTypeLine : DataType 
    { 
     public DataTypeLine() 
     { 
      Console.WriteLine("DataTypeLine just created."); 
     } 
    } 

    public class DataTypeWholeNumber : DataType 
    { 
     public DataTypeWholeNumber() 
     { 
      Console.WriteLine("DataTypeWholeNumber just created."); 
     } 

     //new public override string GetBuildItemBlock() //base method is erroneously executed 
     //public override string GetBuildItemBlock() //gets error "cannot override inherited member because it is not marked virtual, abstract, or override" 
     public override string GetBuildItemBlock() 
     { 
      return "GetBuildItemBlock executed in the WHOLENUMBER class."; 
     } 
    } 

} 
+0

下面是關於(罕見)情況的一些說明,其中人們可能想要使用「新」進行方法隱藏。 http://blogs.msdn.com/ericlippert/archive/2008/05/21/method-hiding-apologia.aspx – 2009-06-16 15:20:29

回答

8

virtual/override是核心多態性對;聽起來像是你已經破解這些

abstract就像virtual,但有沒有合理的基本實現;用例:或許一個Stream,其中它是必要爲實際執行某些字節。這迫使班級成爲abstract

new通常應該避免;它破壞了多態性......最常見的情況是用更具體的簽名/返回類型重新公開(可能是在密封的類中,因爲它沒有在鏈上變得更漂亮......) - 參見SqlConnection.CreateCommand(vs DbConnection.CreateCommand),或(也許更值得注意的)IEnumerator<T>.Current(VS IEnumerator.Current

4

看起來你已經從你的例子想通了virtualoverride,所以:

  • 'abstract' 也可以在會員申請而不是'virtual',在這種情況下,您並未指定該方法的實施(''簽字後直接簽字'')。這迫使所有具體的後代實施該方法。

  • 'new'與繼承無關,但可以用在成員的後代類中以隱藏基類中具有完全相同簽名的成員。

簡而言之)

1

此外到其他的答案。

覆蓋您希望允許子類執行自己的處理,不進行處理,甚至只是爲某個函數調用父類處理。重寫或虛函數不一定要在後代類中實現。

摘要當您不希望在您的基類中執行任何處理,但希望該方法由任何繼承類實現時。 (最好,當繼承類行爲可以大大不同)。如果一個類只包含抽象方法,那麼它實際上是一個接口類型。指定爲抽象的函數必須在子類中實現(如果不是,編譯器將拋出錯誤)。