2008-12-11 67 views
8

对不起,我认为这是一个继承问题:它始终是一个ArrayList问题!在Java中的ArrayList之间进行Casting

好吧,我的问题比我想象的更具体。所以我有两个班的家庭。卡和区域。区域是拿着卡片的盒子。

Zone的前两个子类,ZoneList和ZoneMap意味着存储卡的两种不同方式。更多的子类,例如Hand和PokerHand,都有自己特定的处理卡片的方式。

如果它变得复杂的是,卡也有子类,例如扑克卡,并且ZoneList和ZoneMap的子类是用来组织这些子类的。

所以在ZoneList中我有protected ArrayList<Card> cardBox;和PokerHand,因为PokerCard是一张卡片,所以我希望能够申报cardBox = new ArrayList<PokerCard>();。我得到的错误是我显然无法在CardLists和GangCard之间进行ArrayLists ...所以我试图通过在PokerHand中重新声明cardBox为private ArrayList<PokerCard> cardBox;来解决此问题,但导致隐藏的是窃听启动我的程序。

所以,真的,问题是关于在ArrayLists之间进行投射吗? Java告诉我我不能,所以我有什么想法?

z。

+0

试想想吧!我认为另一种情况是类似的,当我调用getElementAt();它回到了我的GImage,我不能像GImage那样对待!当我尝试调用GImage.getName()时,Java获得了所有的支持。或什么的,因为它不是一个图像它是一个对象...! – Ziggy 2008-12-11 06:19:25

回答

11

如果我理解正确的话,你应该声明:

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

public class PokerHand extends ZoneList<PokerCard> { 
    public PokerHand() { 
     cardBox = new ArrayList<PokerCard>(); 
    } 
} 
+0

哦,伙计!太好了。我完全一直在想“如果我知道如何将类型作为参数传递,这不会很好吗?”而现在我完全可以做到!朋友! – Ziggy 2008-12-11 07:12:59

1

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

这里是Java基本访问控制的很好的链接:

http://java.sun.com/docs/books/tutorial/java/javaOO/accesscontrol.html

这个你也可能会发现有用的

http://java.sys-con.com/node/46344

+0

我不认为这是一个访问控制问题 - 这是一个通用的方差问题。 – 2008-12-11 07:49:02

10

首先,它通常是更好的做法是使用getter/setter方法,而不是直接访问属性,特别是如果你要做很多复杂的继承。

对于仿制药的问题,你可以尝试定义cardBox吸气剂超(或顶层接口/抽象类)为:

protected ArrayList<? extends Card> getCardBox(); 

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

+0

啊!我不知道我能做到这一点:太棒了!谢谢! – Ziggy 2008-12-11 07:11:54

+0

当使用这个<?扩展Card> thingy,我应该如何去初始化ArrayLists?只是普通的旧盒子=新的ArrayList ();返回我一个错误?... – Ziggy 2008-12-11 09:08:08

+1

在子类中,您将实例化一个列表作为属性,其中'private final列表 cardBox = new ArrayList ()'此列表将由getCardBox方法返回。 – boutta 2008-12-11 09:57:15

19

Marc和kolstae在如何解决这个问题方面都给予很好的答案,但我认为这是值得说明的是为什么你原来的代码不起作用。

为了简化问题,我倾向于把问题放在水果方面。假设我们有:

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

如果这是允许的,我们最终在一串香蕉,这显然是一件坏事,一个苹果。那么,问题在哪里?第一行必须没问题,第三行必须没问题 - 你可以添加任何种类的水果到List<Fruit> - 所以问题必须在第二行。这是禁止的,正是为了避免这种问题。

这有帮助吗?

6

如上所述,您不能将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); 
} 
4

的一种方式做到这一点是铸造最早ArrayList的:

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