簡體   English   中英

抽象基類還是類?

[英]Abstract Base Class or Class?

對於我的學期項目,我的團隊和我應該創建一個包含游戲開發框架並展示OOP概念的.jar文件(庫,不可運行)。 它應該是一個框架,另一個團隊應該使用我們的框架,反之亦然。 所以我想知道我們應該如何開始。 我們想到了幾種方法:
1.從普通課開始

public class Enemy {
    public Enemy(int x, int y, int health, int attack, ...) {
        ...
    }
    ...
}
public class UserDefinedClass extends Enemy {
    ...
}

2.從一個抽象類開始,用戶定義的敵人必須繼承抽象成員

public abstract class Enemy {
    public Enemy(int x, int y, int health, int attack, ...) {
        ...
    }
    public abstract void draw();
    public abstract void destroy();
    ...
}
public class UserDefinedClass extends Enemy {
    ...
    public void draw() {
        ...
    }
    public void destroy() {
        ...
    }
}

3.創建ALL繼承的超級ABC(抽象基類)

public abstract class VectorEntity {
    ...
}
public abstract class Enemy extends VectorEntity {
    ...
}
public class Player extends VectorEntity {
    ...
}
public class UserDefinedClass extends Enemy {
    ...
}

我應該使用哪個? 或者,還有更好的方法?

嗯,如果不深入了解你正在做什么,有點難以肯定,即便如此,這也是相當主觀的。 但是,有些事情需要考慮,可以告訴你。

  1. 他們是否會真正實例化敵人,或者所有敵人真的需要屬於派生類型嗎? 如果你實際上並不是要實例化Enemies而不是派生類型,那么它應該是一個接口或一個抽象類。

  2. 如果您希望在基類中提供實際行為,那么顯然它需要是一個類而不是一個接口。

  3. 需要為API提供但對您提供任何實現沒有任何意義的方法應該是抽象的。

  4. 在基類中實現它們很有意義的方法應該在基類中有實現。 如果它們被覆蓋的意義不大,那么讓它們成為最終的。

  5. 讓類共享一個共同的基類真的只有在他們真正分享行為或者你需要能夠在代碼中的某個地方處理它們時才有意義。 如果他們真的不那么相似,那么他們可能不應該共享一個基類。 例如,如果Enemy和Player都應該是可顯示的,那么擁有一個處理其顯示功能的公共基類可能是有意義的。 但是如果Enemy是可以顯示的東西,並且Player是一個更抽象的概念 - 比如游戲的控制器 - 並且不可顯示,那么它們分享基類可能沒有意義。 一般來說,在構建類時最好更喜歡組合而不是繼承,所以如果有問題的類實際上不是共享行為而且實際上與公共基類沒有“is-a”關系,那么他們不應該共享一個共同的基類。

  6. 希望您的基類只共享方法,而不是數據。 換句話說,在繼承樹中,最好只有葉子是可實例化的。 有各種各樣的東西,比如equals() ,當你有基類和實際數據時會崩潰。 這並不是說你不能這樣做 - 人們總是這樣做 - 但它可能會導致問題,如果不需要,最好避免。

  7. 更喜歡覆蓋抽象方法。 否則,在派生類中,您可能無法調用基類的方法或完全改變方法的作用。

我確信我可以提出更多,但如果沒有真正熟悉你的項目,它必然是相當通用的。 在你提供的3個選項中,我可能會選擇2. 3看起來你可能正在為不相關的類創建一個基類,而1會導致Enemy被實例化,你可能不需要和肯定會使你的繼承層次結構中的葉子不僅可以實例化。 你可能仍然會在基類中使用2來獲得數據,但是你更有可能只重寫抽象方法,並且在派生類中改變行為的問題會更少。

第四種選擇是使用接口。

interface Enemy {

    public void draw();

    . . .

}

如果你剛剛開始,我會避免你的第三個選擇。 讓框架發展一點,看看是否需要它。

我的行為准則是​​,只要有多個類共享相同的操作/數據/方法/功能,它們就應該是同一個抽象類的擴展。

所以,如果是我這樣做:

  • 如果所有類都有共同點,請使用頂級abstract class ,在一個位置收集此功能/字段/數據。
  • 如果他們不這樣做,只有那些實際上有共同點的類應該擴展一個低級abstract class

如果只有方法是類的共同點,那么也可以使用interface 但是,我總覺得我遲早會看到實現interface的類具有相同的private字段。 此時,我將interface轉換為包含這些私有字段的abstract class (如果沒有其他內容則保存在代碼行上)。

只是“更有效的c ++”第271頁中的一個小答案:

“使基類不抽象,而不是在層次結尾”。 我懶得給你整個教練,但是autor列出了一些很好的理由。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM