我想我在这里缺少一些基本的东西。在写一个卡片游戏应用程序时,我定义了一个Card类,然后是这种形式的各种卡片集合:
ArrayList<Card> cards;
现在我可以继续使用所有相应的ArrayList方法。
在某些时候我厌倦了编写ArrayList,还需要创建ArrayList数组,所以定义一个这样的包装类:
class CardList {
protected ArrayList<Card> cards;
...overrides and class methods down here...
}
但是现在当我实例化一个CardList(比如说MyCardList)时,我已经失去了对底层ArrayList方法的访问权限,所以我似乎可以选择:
(a)将卡暴露为受包保护的成员,因此我可以编写MyCardList.cards.someArrayListMethod()OR
(b)或在CardList中为我想要使用的每个ArrayList方法实现直通方法
哪个更好,或者我在这里绝望地走了?
答案 0 :(得分:2)
您可以像这样创建一个包范围的类:
class CardList extends ArrayList<Card> {
// Literally no need for anything here unless you want
// constructors that accept capacity, etc.; the default
// constructor will be provided
}
...然后只使用它:
CardList list = new CardList();
list.add(new Card());
// ...
但通常最好对接口进行编码,在这种情况下:
interface CardList extends List<Card> {
// No need for anything here
}
和
class CardListImpl extends ArrayList<Card> implements CardList {
// No need for anything here unless you want constructors
// that accept capacity, etc.
}
并使用它:
CardList list = new CardListImpl();
list.add(new Card());
// ...
...如果您愿意,只需更改一个文件即可切换到LinkedList<Card>
。
或者就此而言,您并不真正需要CardList
界面 - CardList
只比List<Card>
短两个字符。那就是:
class CardListImpl extends ArrayList<Card> {
// No need for anything here unless you want constructors
// that accept capacity, etc.
}
并使用它:
List<Card> list = new CardListImpl();
list.add(new Card());
// ...
...如果您决定切换具体列表类的类型,则只需在一个地方执行此操作。
答案 1 :(得分:1)
直接曝光卡片总是一个坏主意。如果您需要访问它,请使用getter(公共,受保护或受保护的包装)进行操作。如果您公开该字段,您可能会冒着用户将其设置为null的风险
如果你愿意,可以委托arraylist方法,如果你在CardList中组合了几个元素,那就更有意义了
另一种可能性是扩展ArrayList,但只有在你想要特定功能的情况下才有意义(例如,在添加已经在列表中的卡时你可能需要特定的行为)
第四种可能性是仅委派您需要的方法,这使您可以自由地更改实现(例如,如果每张卡都是唯一的,您可以使用int或long来跟踪每张卡的存在而不是它的存在在列表中)