2009-05-24 15 views

回答

4

我不明白爲什麼ABC無法正確地擁有每個實例(又稱非靜態)數據成員,因爲需要支持它提供給子類的方法。以ABC存在的常見情況提供模板方法DP(鉤子方法是抽象的) - 如果組織方法的一部分功能是更新一些實例變量(例如,計數多少次方法被調用),那麼顯然這些變量也應該由ABC提供。你能更好地解釋爲什麼你認爲這是壞的設計?!

+0

同意。抽象類中的數據成員可以幫助程序員多次實現它們,並提供通過它訪問它們的單一類型; – 2009-05-24 10:28:12

+0

在閱讀了關於模板方法模式之後,我認爲這是一個非常好的理由。我從許多「大」C++書籍中讀到ABC不應該有數據,所以我想知道是否有例外。 – rlbond 2009-05-25 05:40:12

0

我在插件體系結構中看到了這一點,如Paint.NET的。

0

控制反轉可能需要這樣做。例如,你有一堆需要Logger實例的類,它們基於的抽象類可能有一個構造函數將其存儲在成員變量或私有屬性中(假設你記得調用基構造器grin

1

抽象類可以擁有任何它需要的成員來支持它提供給從它繼承的類的功能。這並不是說這些子類可以直接訪問:它們可能只是通過子類或它們的客戶端進行的方法調用來讀取和更改。

0

這是OK,當你的抽象類的數據成員包含基本代碼爲繼承類

我會考慮使用一個接口,當數據成員僅僅是描述你的類

0

是的,它可能在抽象基類中提供成員變量,意圖使其子類將使用這些成員來實現具體的實現。

下面是一個具體的例子,使用我們都喜歡的汽車比喻。

比方說我們做Car一個抽象基類,它有輪子,底盤佔位符,併爲其它的子類的引擎使用:

abstract class Car { 
    Wheels wheels 
    Chassis chassis 
    Engine engine 

    abstract void accelerate(); 
    abstract void decelerate(); 
} 

現在,擴展Car,會員類已經存在使用,使一個子類的責任是填充這些成員變量:

class NiceCar extends Car { 
    Decoration decoration; 

    public NiceCar() { 
     wheels = new ChromeWheels(); 
     chassis = new LightweightCompositeChassis(); 
     engine = new LotsOfHorsepowerEngine(); 
     decoration = new CoolRacingStripes(); 
    } 

    void accelerate() { 
     engine.feedFuel(); 
    } 

    void decelerate() { 
     wheels.applyBrakes(); 
    } 
} 

如可以看到的,抽象基類可以作爲一個藍圖哪些組件(成員變量)加工對象物S應該填寫以獲得課程的全部功能。在這種情況下,Car提供了在具體實施中使用的汽車的基本部件。 NiceCar使用這些成員字段併爲其自己的功能添加一些功能,例如裝飾性油漆作業。

0

我懷疑你正在圍繞抽象基類的概念畫一圈太緊的圈。

抽象基類(與純接口相對)是一個類,它的某些功能旨在被子類使用。因此它將具有一些功能以及旨在被覆蓋的方法(界面部分)。這個功能沒有理由不具有與它相關的成員變量。

許多框架都是基於繼承。這些將幾乎不可避免地具有成員變量的抽象類。例如,DirectShow是Windows中的多媒體流式傳輸框架。信源,編碼器,解碼器等都是在所謂的「濾波器」中實現的。有各種類型的過濾器的基類。它們中的每一個都有成員變量,用於上游和下游過濾器,協商媒體類型等。

0

如果它是所有繼承類使用的狀態,我認爲它是強制性將其移到基類。儘管基礎是抽象的。我認爲大多數人在重構會同意我這一點。

爲什麼一些州應該在基地可能有幾個原因。減少代碼重複是一個很好的理由。

乾杯!

編輯:請告訴我你爲什麼投票,所以我可以改進。謝謝!

0

正如其他人所提到的,當需要存儲狀態時,實例字段會添加到任何類別的類中。這對於抽象類或具體類都適用 - 沒有區別。

爲什麼它應該有所作爲?畢竟抽象類就像任何類一樣,除非它不能被instantiate,需要繼承類來完成這個類。

相關問題