如果我能用抽象類做的所有事情,我可以做一個普通的超類, 爲什麼我會使用抽象類,當我可以使用一個普通的超類?抽象與普通超類
抽象與普通超類
回答
基類提供它們自己的方法實現。這些實現有時可以被覆蓋(取決於語言)。
抽象類不提供默認實現,每個繼承類都需要根據具體情況實現方法。
以上細節可能因語種而異。閱讀相應的文檔。
考慮這個例子:
甲Number
抽象類具有add()
方法。 A OddNumber
和EvenNumber
子類需要實現幾乎相同的add()
方法,因此存在一些代碼重複。在這裏,擁有一個超類更有意義(或者至少具有Number
的子類RealNumber
)。
然而,考慮Complex
爲的Number
一個子類,如果人數分別爲不是抽象的,在Number
發現(假設它是一個真正的數相加的算法)將毫無意義爲複數的add()
方法。這裏抽象類更有意義。有些語言可以讓你重寫超類方法,但在這種情況下這有點笨拙。
出於興趣,您將何時使用抽象添加方法,以及您希望何時使用* addable *接口。我在問,因爲我的直覺告訴我喜歡接口繼承。 – jsj
對我來說,「可加接口」界面看起來有點笨重,即使它在邏輯上合理。要回答你的問題,這只是一個設計決定。您可以使用接口,超類或抽象類。我喜歡使用許多不相關對象可能需要提供特定功能(例如,日誌記錄)的接口。 –
我認爲評論和回答已經暗示了這一點,但我想更直白地說:你不能用一個普通的超類來做所有事情,你可以用一個抽象類來做。一個抽象類可以讓你定義一個方法的簽名而不包含它的實現,而一個抽象類將不允許你直接實例化它。
因此,如果我有一個類簽名記住3種方法,我不想分享任何他們的實現,我會使用一個接口。 如果我想共享這些方法之一的實現,我將使用一個抽象類,然後使該類中的兩個方法抽象化。 如果我想共享方法的所有實現,我將使用一個抽象類,如果它直接實例化它永遠沒有意義,或者如果它真的使用常規類。
(這是基於我在C#中的經驗。詳情語言之間的差異。)
抽象類是非常有用的,當你需要代表一種常見的方式很多類似的事情。
例如,假設您想用代碼表示一個動物園,並且您需要購買食品雜貨清單以確保您有合適的食物。你如何代表所有動物最喜歡的食物?什麼噪音都造成了?他們如何移動?你可以嘗試使用超持有的食物,噪音和運動的大名單,但它更容易有共同定義的動物,然後讓每個動物提供它自己的實現細節:
public class Zoo {
public Animals[] AnimalsInZoo { get; set;}
public List<Food> GetGroceryList(){
List<Food> groceries = new List<Food>();
foreach(Animal a in Animals[]){
groceries.Add(a.FavoriteFood);
}
return groceries;
}
public void MakeAnimalsSing(){
foreach(Animal a in Animals[]){
a.MakeNoise();
}
}
}
抽象動物類會是什麼樣子:
public abstract class Animal {
public abstract void MakeNoise();
public abstract Food FavoriteFood { get; }
public abstract void Move();
}
並說動物園有兩種類型的動物:
public class Panda : Animal{
public override void MakeNoise(){
// grunt
}
public override void Move(){
// walk
}
public override Food FavoriteFood {
get {
return new Bamboo();
}
}
}
public class Parrot: Animal{
public override void MakeNoise(){
// talk
}
public override void Move(){
// fly
}
public override Food FavoriteFood {
get {
return new Cracker();
}
}
}
由於具有共同的抽象類,我可以很容易地與任何NU工作許多不同的動物類型,而不必明確地知道我正在使用哪一種動物類型,但每種類型都可以以他們自己的方式行事。
超類無法提供這種靈活性或細節。
您正在描述多態,但通常不需要抽象類來在面嚮對象語言中實現這一點。在上面的代碼中,您可以使用所有虛擬方法或Animal界面對Animal超類執行相同的操作。 – MichaC
- 1. Java - 抽象類到普通類
- 2. 抽象超類
- 3. 抽象類和非抽象超類
- 4. 抽象與抽象類
- 5. 抽象類擴展和普通類之間的區別延伸
- 6. 普通類擴展到另一個抽象類
- 7. 與抽象類
- 8. 與抽象類
- 9. C#抽象方法和普通代碼
- 10. 對象是抽象類的超類嗎?
- 11. Symfony2/Doctrine - 與普通SQL相關的實體抽象
- 12. 抽象類與automapper
- 13. 作爲超類型的抽象基類與具體類
- 14. 在抽象類中調用超類
- 15. FactoryClass與普通Java類
- 16. 的Bug的EclipseLink 2.0與普通超
- 17. 抽象超類傳遞超類型返回類型
- 18. 通用抽象類型C++
- 19. @JvmField對通用/抽象類
- 20. 抽象類構造函數和普通類構造函數的區別?
- 21. @classmethod與抽象基類
- 22. 抽象類MouseAdapter與接口
- 23. Morphia InstantiationException與抽象@Embedded類
- 24. 100%抽象類與接口
- 25. 與接口和抽象類
- 26. 抽象類與掃描儀
- 27. 接口與抽象類
- 28. Java Web服務/ JAXB - 抽象超類
- 29. C++:段訪問抽象超類'enum
- 30. 在抽象超類中覆蓋克隆
抽象強制在子類中的實現,並允許定義但未實現的行爲。 –