English 中文(简体)
在Java中,ArrayList之间的转换
原标题:
  • 时间:2008-12-11 06:09:35
  •  标签:

抱歉,我以为这是一个继承问题:原来这是一个ArrayList问题!

好的,我的问题比我想象的更具体。我有两个类族。卡牌和区域。区域是用来容纳卡牌的盒子。

Zone的前两个子类,ZoneList和ZoneMap,旨在存储卡牌的两种不同方式。进一步的子类,如手牌(Hand)和扑克牌手(PokerHand),有其自己特定的处理存储的卡牌的方式。

问题变得复杂的地方在于,Card还有子类,比如PokerCard,而ZoneList和ZoneMap的子类是用来组织它们的。

所以在ZoneList中,我有protected ArrayList<Card> cardBox;,在PokerHand中我希望能够声明cardBox = new ArrayList<PokerCard>();,因为PokerCard是一张卡。我得到的错误是,当涉及ArrayLists时,我显然无法在Card和GangCard之间进行转换...所以我试图通过在PokerHand中重新声明cardBox为private ArrayList<PokerCard> cardBox;来修复这个问题,但这导致了隐藏和程序故障。

所以,问题实际上是怎样在ArrayList之间进行强制转换?Java告诉我不能这样做,那么您有什么办法呢?

抱歉,这个太短,并无法确定它的意义。请提供更多信息以便我为您提供翻译。

最佳回答

如果我理解您的意思正确,您应该声明:

public class ZoneList<T extends Card> {
   protected List<T> cardBox;
}

public class PokerHand extends ZoneList<PokerCard> {
   public PokerHand() {
      cardBox = new ArrayList<PokerCard>();
   }
}
问题回答

马克和科尔斯特在解决问题方面给出了很好的答案,但我认为值得解释一下为什么你原来的代码不起作用。

为了简化问题,我倾向于用水果来表达问题。假设我们有:

List<Banana> bananaBunch = new ArrayList<Banana>();
List<Fruit> fruitBowl = bananBunch;
fruitBowl.add(new Apple());

如果是允许的,我们最终会在一堆香蕉中得到一个苹果,这显然是不好的事情。那么,问题出在哪里?第一行必须没问题,第三行必须没问题 - 你可以把任何一种水果添加到List<Fruit>中 - 因此问题必须出在第二行。这正是被禁止的,以避免这种问题的发生。

那会有所帮助吗? (nà huì yǒu suǒ bāng zhù ma?)

首先,通常最好的做法是使用getter/setter方法而不是直接访问属性,尤其是如果您将要进行大量复杂的继承。

关于泛型问题,您可以尝试在超类(或顶级接口/抽象类)中定义cardBox getter,如下:

protected ArrayList<? extends Card> getCardBox();

这样你就可以在子类中覆盖它,并让它们返回任何类型的 Card 子类列表。

一个方法是首先将其转换为ArrayList:

ArrayList<Card> cards = (ArrayList<Card>)(ArrayList<?>) (pokerCardObjects);

没有投掷的其他替代方法:

用流:

ArrayList<Card> cards = pokerCardObjects.stream().collect(Collectors.toCollection(ArrayList::new);

或者创建一个新的ArrayList:

ArrayList<Card> cards = new ArrayList<>(pokerCardObjects);

正如所述,您不能将ArrayList<PokerCard>强制转换为ArrayList<Card>,但您可以将ArrayList<PokerCard>强制转换为ArrayList<? extends Card>。或者最好将List<? extends Card>用作您的返回值,因为您可能无论如何都不依赖于ArrayList的实现:

protected ArrayList<? extends Card> getCardBox();

关于您在评论中提出的问题,构造方式应该按照您描述的那样工作:List<? extends Card> list = new ArrayList<Card>();。您可能需要填充您的列表,因此该方法可能类似于以下内容:

protected ArrayList<? extends Card> getCardBox() {
    List<Card> list = new ArrayList<Card>();
    list.add(pokerCard1);
    list.add(pokerCard2);
    return java.util.Collections.unmodifiableList(list);
}

这将取决于 Zonelist 中的Arraylist的访问控制。我的假设是它要么未标记,要么为公共或受保护。子类可以通过定义具有相同名称的变量来“隐藏”它可以访问到的父类变量。您还可以使用 this 关键字来引用特定的对象实例,以及 super 关键字来引用父级。

这是一个关于Java基本访问控制的好链接:

http://java.sun.com/docs/books/tutorial/java/javaOO/accesscontrol.html 的中文翻译为:访问控制。

这可能对您也有帮助。

将此翻译为中文:http://java.sys-con.com/node/46344 http://java.sys-con.com/node/46344





相关问题