Pregunta

Lo siento, pensé que esto era una herencia pregunta:fue un ArrayList pregunta a lo largo de todos!

Ok, mi problema es más específico de lo que yo pensaba.Así que tengo dos familias de clases.Tarjetas y Zonas.Las zonas son las cajas para la celebración de la tarjeta.

Las dos primeras subclases de la Zona, ZoneList y ZoneMap están destinados a ser dos diferentes formas de almacenamiento de las Tarjetas.Además de las subclases, tales como la Mano, y PokerHand, tienen sus propias maneras de lidiar con las tarjetas de la tienda.

Donde es complicado es que la Tarjeta también tiene subclases, como PokerCard, y que las subclases de ZoneList y ZoneMap tienen el propósito de organizar a los.

Así, en ZoneList tengo protected ArrayList<Card> cardBox; y en PokerHand esperaba ser capaz de declarar cardBox = new ArrayList<PokerCard>(); desde PokerCard es una Tarjeta.El error que estoy consiguiendo es que al parecer no pueden lanzar entre la Tarjeta y el GangCard cuando se trata de ArrayLists...Así que yo estaba tratando de solucionar este problema, simplemente declararlo como cardBox private ArrayList<PokerCard> cardBox; dentro de PokerHand, pero que resultó en la clandestinidad que estaba molestando a mi programa.

ASÍ que en realidad, la pregunta es acerca de casting entre ArrayLists?Java me dice que no puede, así que cualquier idea sobre cómo puedo?

z.

¿Fue útil?

Solución

Si he entendido bien, probablemente debería declarar:

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

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

Otros consejos

Marc y kolstae han dado buenas respuestas en términos de cómo evitar el problema, pero creo que vale la pena explicar ¿Por qué su código original no funciona.

Para simplificar las cosas, que tienden a poner el problema en términos de fruta. Supongamos que tenemos:

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

Si esto se permite, nos encontramos con una manzana en un racimo de plátanos, lo que obviamente es una mala cosa. ¿Entonces, dónde está el problema? La primera línea tiene que estar bien, y la tercera línea tiene que estar bien - se puede añadir cualquier tipo de fruta a List<Fruit> - por lo que el problema tiene que estar en la segunda línea. Eso es lo que está prohibido, precisamente para evitar este tipo de problema.

¿Le ayuda en absoluto?

En primer lugar, por lo general es mejor la práctica de utilizar métodos de captador / definidor de acceder a las propiedades directamente, especialmente si usted va a estar haciendo un montón de herencia complicada.

En cuanto al problema de los genéricos, usted podría tratar de definir el captador cardbox en la superclase (o de alto nivel de interfaz / clase abstracta) como:

protected ArrayList<? extends Card> getCardBox();

De esa manera usted puede ovverride en subclases y hacer que devuelven una lista de cualquier tipo de subclase de la tarjeta.

Una forma de hacerlo es mediante la fundición a ArrayList primero:

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

Otra de las alternativas sin poner:

Con secuencias:

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

o la creación de un nuevo ArrayList:

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

Como se ha dicho, no se puede echar a ArrayList<PokerCard> ArrayList<Card>, pero se puede echar a ArrayList<? extends Card> List<? extends Card>. O mejor uso List<? extends Card> list = new ArrayList<Card>(); como su valor de retorno, porque es probable que no se basan en la aplicación de todas formas ArrayList:

protected ArrayList<? extends Card> getCardBox();

En cuanto a su pregunta en el comentario, la construcción debe funcionar como se describe a continuación: <=>. Es probable que tenga que llenar su lista, por lo que el método es probablemente algo como esto:

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

Esto va a depender de lo que el control de acceso está en la Arraylist en Zonelist. Mi hipótesis de la declaración depurador es que es bien marcado, pública o protegida. Una subclase puede "ocultar" una clase variable de los padres que tiene acceso a mediante la definición de una variable con el mismo nombre. También puede utilizar this palabra clave para referirse a la instancia del objeto en particular y super palabra clave para referirse al padre.

Aquí es un buen enlace en el control de acceso básico en Java:

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

Esto también pueden ser útiles

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top