2012-10-26 37 views
4

如果我能用抽象類做的所有事情,我可以做一個普通的超類, 爲什麼我會使用抽象類,當我可以使用一個普通的超類?抽象與普通超類

+1

抽象強制在子類中的實現,並允許定義但未實現的行爲。 –

回答

1

基類提供它們自己的方法實現。這些實現有時可以被覆蓋(取決於語言)。

抽象類不提供默認實現,每個繼承類都需要根據具體情況實現方法。

以上細節可能因語種而異。閱讀相應的文檔。

考慮這個例子:
Number抽象類具有add()方法。 A OddNumberEvenNumber子類需要實現幾乎相同的add()方法,因此存在一些代碼重複。在這裏,擁有一個超類更有意義(或者至少具有Number的子類RealNumber)。

然而,考慮Complex爲的Number一個子類,如果人數分別爲不是抽象的,在Number發現(假設它是一個真正的數相加的算法)將毫無意義爲複數的add()方法。這裏抽象類更有意義。有些語言可以讓你重寫超類方法,但在這種情況下這有點笨拙。

+0

出於興趣,您將何時使用抽象添加方法,以及您希望何時使用* addable *接口。我在問,因爲我的直覺告訴我喜歡接口繼承。 – jsj

+0

對我來說,「可加接口」界面看起來有點笨重,即使它在邏輯上合理。要回答你的問題,這只是一個設計決定。您可以使用接口,超類或抽象類。我喜歡使用許多不相關對象可能需要提供特定功能(例如,日誌記錄)的接口。 –

10

我認爲評論和回答已經暗示了這一點,但我想更直白地說:你不能用一個普通的超類來做所有事情,你可以用一個抽象類來做。一個抽象類可以讓你定義一個方法的簽名而不包含它的實現,而一個抽象類將不允許你直接實例化它。

因此,如果我有一個類簽名記住3種方法,我不想分享任何他們的實現,我會使用一個接口。 如果我想共享這些方法之一的實現,我將使用一個抽象類,然後使該類中的兩個方法抽象化。 如果我想共享方法的所有實現,我將使用一個抽象類,如果它直接實例化它永遠沒有意義,或者如果它真的使用常規類。

(這是基於我在C#中的經驗。詳情語言之間的差異。)

-1

抽象類是非常有用的,當你需要代表一種常見的方式很多類似的事情。

例如,假設您想用代碼表示一個動物園,並且您需要購買食品雜貨清單以確保您有合適的食物。你如何代表所有動物最喜歡的食物?什麼噪音都造成了?他們如何移動?你可以嘗試使用超持有的食物,噪音和運動的大名單,但它更容易有共同定義的動物,然後讓每個動物提供它自己的實現細節:

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工作許多不同的動物類型,而不必明確地知道我正在使用哪一種動物類型,但每種類型都可以以他們自己的方式行事。

超類無法提供這種靈活性或細節。

+0

您正在描述多態,但通常不需要抽象類來在面嚮對象語言中實現這一點。在上面的代碼中,您可以使用所有虛擬方法或Animal界面對Animal超類執行相同的操作。 – MichaC