2010-04-26 88 views
2

可能重複:
What is an abstract class ?爲什麼需要抽象類?

1.什麼是創建一個不能被實例化一個類的呢?

通常用作基類或接口(某些語言具有單獨的接口構造,有些則不) - 它不知道實現(即由子類/實現類提供)

2.爲什麼會有人想要這樣的班級?

For abstraction and re-use 

3.什麼是抽象類成爲必要的情況?任何人都可以用一個例子來簡要介紹一下嗎?

+0

這是一個愚蠢的愚蠢。 – slugster 2010-04-26 12:31:14

回答

5

抽象類允許您編寫一段通用的代碼,將特定決策推遲到派生類,從而減少代碼重複。

+0

@OtávioDécio:當基類不能爲方法提供有意義的默認實現時必需? – bala3569 2010-04-26 12:26:34

+1

@ bala3569:抽象基類*可以爲方法(或大部分方法)提供有意義的默認實現。看到我的答案。 – 2010-04-26 12:28:57

4

當您創建一個繼承樹時,您可能需要抽象類,並且不能實例化一個單獨的祖先,僅僅因爲未知如何實現一些方法。

標記一個類爲抽象告訴編譯器有:

  • 例1
    如果你需要一個CarBicycle一個祖先,你可能會創建一個Vehicle類。你不能啓動這個Vehicle類,因爲它是未完成的。 A Vehicle本身不起作用。這就是爲什麼Vehicle將是抽象的。

  • 實施例2
    從.NET框架另一個實例。 Stream類是提供基本I/O功能的抽象類。它提供了一個讀寫方法來處理下層流的字節。

該物流可以是FileStreamNetworkStreamMemoryStream,等等。 Stream本身不知道如何讀取或寫入流的具體實現。但是實現了Stream的一些方法,因爲它們被流的所有實例共享。

這是不可能與一個接口。所以你需要創建一個類。由於ReadWrite方法無法執行,因此Stream被標記爲抽象。這將阻止Stream類按原樣創建。

2

抽象類絕不是必須的。你總是可以使用一個非抽象類,併爲本來是抽象的方法提供存根。您也可以通過僅爲受保護的構造函數提供類來近似抽象的方面。

但這不是重點。當一個類用於對一組子類的廣義屬性和行爲進行建模時,您需要將其標記爲抽象,以使您的意圖清晰。

2

我知道我需要在執行應用程序的時間之間保存信息。

我大概知道我需要什麼方法來完成這個。我也可以提供幾種執行整個數據存儲操作的各個部分的方法。

我知道我的客戶根據偏好(MS Sql,Oracle)和法律(健康行業安全要求)對數據存儲有不同的要求。

我該如何提供一個可以完成80%重物提升的對象,但最後的20%會自動定製?

抽象基類允許我們爲每個客戶自定義最後的20%,並重用基類中80%的通用代碼。此外,抽象類不會受到versioning issues that interfaces face的影響,這是一項獎勵。

我可以編寫我的應用程序,提供抽象基類的默認實現,測試它並部署它,而不必爲每個客戶端擁有不同的版本。當客戶請求不同的存儲方法時,可以通過dependency injection在運行時提供和使用不同的實現。

6

這不是抽象類總是必要,但他們往往很方便。假設我想爲特定類型的文本文件編寫解析器。

// hasty code, might be written poorly 
public abstract class FileParser<T> { 
    private readonly List<T> _contents; 
    public IEnumerable<T> Contents { 
     get { return _contents.AsReadOnly(); } 
    } 

    protected FileParser() { 
     _contents = new List<T>(); 
    } 

    public void ReadFile(string path) { 
     if (!File.Exists(path)) 
      return; 

     using (var reader = new StreamReader(path)) { 
      while (!reader.EndOfStream) { 
       T value; 
       if (TryParseLine(reader.ReadLine(), out value)) 
        _contents.Add(value); 
      } 
     } 
    } 

    protected abstract bool TryParseLine(string text, out T value); 
} 

東西扔在一起,就像上面後,我已經完成了樣板代碼的任何FileParser -esque類需要。所有我需要爲任何派生類做的只是重寫一個抽象方法 - 而不是寫所有處理流等乏味的東西,而且,我可以稍後輕鬆地添加功能 - 例如異常處理 - 它將適用於所有派生類。

相關問題