2011-02-17 63 views
4

畢竟任何java抽象都是Object的抽象子類。有時候我們需要強制子類實現一些方法,但是可能已經有了一個定義良好的具有特定類的層次結構。爲什麼要有一個抽象的具體類壞設計的子類?

例如:我有 車輛< ---汽車

一個運作良好的層次,現在我想ElectricCar添加到這個層次。

車輛< - 汽車< - 電動汽車。

我也希望所有的不同類型的電動車來實現某些行爲,如getBatteryLife或something-

它爲什麼會是一個壞主意,使ElectricCar抽象?

+9

誰說這是壞設計? – SLaks

回答

2

使它變得抽象沒有錯。如果你的企業要求你把它抽象化,那很好。就像你說的那樣,Java lib中的很多類都是抽象的,並且仍然在擴展Object。

1

本身並不壞。不常見,但不壞。我唯一能想到的就是可理解性:如果我看到一個具體的Car類,我可以實例化,所以我通常會假定它的任何一個孩子也是可實例化的,因爲99%的代碼以這種方式工作。那麼我會感到困惑,關於第二個,關於不能實例化ElectricCar。

0

就我個人而言,我寧願爲ElectricCar定義接口,然後允許實現類定義方法。然後你可以通過另一種機制分享getBatteryLife的行爲。

我已經構建了一些相當深層次的繼承,我傾向於避免它們做到隨着時間的推移而變得脆弱。一個基類可能是有道理的,但我會考慮如何編寫對象模型以儘可能地共享無繼承的行爲。

+0

不確定我同意這一點;從邏輯上來說,ElectricCar既是Car也是IElectricCar,但由於IElectricCar不能從Car中派生出來,因此無法同時使用IElectricCar的實現器作爲Car和IElectricCar,除非IElectricCar要求其實現器具有與Car相同的方法(違反了更多的敏感性和設計原則,而不是具體父母的抽象衍生物)。 – KeithS

+0

我不使用土耳其語符號,所以我的意思是定義接口ElectricCar(IElectricCar),如果他們想要電動汽車的行爲,特定類型的汽車可以實現。我指的是沒有實施ElectricCar,而只是將其作爲接口,並允許特定的Car類型在需要時使用它。 –

1

有人可能會認爲這種模式打破了Liskov Substituion Principle,因爲如果聲明爲抽象(您可以傳遞ElectricCar子類的實例),則無論何時「Car」被期望,都無法傳遞「ElectricCar」。

在這個特殊的例子中,我期望從「汽車」直接繼承具體的電動汽車(氫動力/插件等),因爲它們滿足「是-α」關係,並且是「汽車」。如果您想描述一些他們應該提供的常見行爲和特徵,那麼他們也應該實施Electric Car 接口

看來你真正想要的是從汽車繼承的能力(因爲這就是它們)共享/重複使用電動汽車相關方法的常見實現。在這種情況下,您正在考慮多重繼承問題或需要mixins,這兩者都不直接受Java支持。

在具體層次結構中提供一個抽象類可能是解決這個問題的方法之一,但它並不漂亮。

+0

我認爲里斯科替代原則在這裏不會被打破 - 您**可以**無論何時需要Car都可以通過ElectricCar類型的每個實例(至少,如果「Car」通常不是燃料專用的)。 –

0

在你的例子中,我會說,Car類應該是抽象的(或接口)。但是ElectricCar是抽象的,沒有什麼不對。

相關問題