在Java中使用typedef等价物的包装类;我必须公开类变量吗?

时间:2015-02-01 16:46:07

标签: java arraylist typedef

我想我在这里缺少一些基本的东西。在写一个卡片游戏应用程序时,我定义了一个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方法实现直通方法

哪个更好,或者我在这里绝望地走了?

2 个答案:

答案 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来跟踪每张卡的存在而不是它的存在在列表中)