Fundição entre ArrayLists em Java
Pergunta
Desculpe, eu pensei que esta era uma questão de herança: era uma questão ArrayList ao longo de toda
!Ok, o meu problema é mais específico do que eu pensava. Então, eu tenho duas famílias de classes. Cartões e zonas. As zonas são caixas de cartão segurando.
As primeiras duas subclasses de Zone, zonelist e ZoneMap são destinadas a ser de duas maneiras diferentes de cartões de armazenamento. Outras subclasses, como a mão, e PokerHand, têm suas próprias maneiras específicas de lidar com as cartas que eles armazenam.
Onde fica complicado é que cartão também tem subclasses, como PokerCard, e que as subclasses de zonelist e ZoneMap são destinadas a organizar os.
Assim, em zonelist tenho protected ArrayList<Card> cardBox;
e em PokerHand eu esperava ser capaz de declarar cardBox = new ArrayList<PokerCard>();
desde PokerCard é um cartão. O erro que eu estou recebendo é que eu, aparentemente, não pode lançar entre cartão e GangCard quando se trata de ArrayLists ... Então eu estava tentando corrigir isso por apenas redeclaring cardbox como private ArrayList<PokerCard> cardBox;
dentro PokerHand, mas que resultou na esconder que estava incomodando o meu programa.
Então, realmente, a pergunta é sobre a conversão entre ArrayLists? Java me Eu não posso diz, então alguma idéia de como eu posso?
z.
Solução
Se eu entendi corretamente, você provavelmente deve declarar:
public class ZoneList<T extends Card> {
protected List<T> cardBox;
}
public class PokerHand extends ZoneList<PokerCard> {
public PokerHand() {
cardBox = new ArrayList<PokerCard>();
}
}
Outras dicas
Marc e kolstae deram boas respostas em termos de como contornar o problema, mas acho que vale a pena explicar por seu código original não funciona.
assuntos Para simplificar, eu tendem a colocar o problema em termos de frutas. Suponha que temos:
List<Banana> bananaBunch = new ArrayList<Banana>();
List<Fruit> fruitBowl = bananBunch;
fruitBowl.add(new Apple());
Se isso for permitido, vamos acabar com uma maçã em um cacho de bananas, que é obviamente uma coisa ruim. Então onde está o problema? A primeira linha tem que estar bem, ea terceira linha tem de ficar bem - você pode adicionar qualquer tipo de fruta para List<Fruit>
- assim que o problema tem que ser na segunda linha. Isso é que é proibido, justamente para evitar esse tipo de problema.
Será que isso ajuda em tudo?
Em primeiro lugar, é geralmente melhor prática para usar métodos getter / setter de acessar propriedades diretamente, especialmente se você estiver indo para estar fazendo um monte de herança complicada.
Quanto ao problema genéricos, você pode tentar definir o getter cardbox na superclasse (ou interface de nível superior / classe abstrata) como:
protected ArrayList<? extends Card> getCardBox();
Dessa forma, você pode ovverride-lo em subclasses e tê-los retornar uma lista de qualquer tipo de subclasse de cartão.
Uma maneira de fazer isso é por vazamento de ArrayList em primeiro lugar:
ArrayList<Card> cards = (ArrayList<Card>)(ArrayList<?>) (pokerCardObjects);
Outra alternativas sem seleção de elenco:
Com correntes:
ArrayList<Card> cards = pokerCardObjects.stream().collect(Collectors.toCollection(ArrayList::new);
ou criar um novo ArrayList:
ArrayList<Card> cards = new ArrayList<>(pokerCardObjects);
Como foi dito, você não pode lançar ArrayList<PokerCard>
para ArrayList<Card>
, mas você pode lançar ArrayList<PokerCard>
para ArrayList<? extends Card>
. Ou melhor uso List<? extends Card>
como seu valor de retorno, porque você provavelmente não contam com a implementação ArrayList de qualquer maneira:
protected ArrayList<? extends Card> getCardBox();
Quanto à sua pergunta no comentário, a construção deve funcionar como você descreveu: List<? extends Card> list = new ArrayList<Card>();
. Você provavelmente tem que preencher sua lista, de modo que o método é provavelmente algo como isto:
protected ArrayList<? extends Card> getCardBox() {
List<Card> list = new ArrayList<Card>();
list.add(pokerCard1);
list.add(pokerCard2);
return java.util.Collections.unmodifiableList(list);
}
Isso vai depender do que o controle de acesso está na ArrayList em Zonelist
. Minha suposição a partir da declaração depurador é que ele é ou não marcado, público ou protegido. A subclasse pode variável de uma classe pai "Hide" tem acesso a através da definição de uma variável com o mesmo nome. Você também pode usar palavra-chave this
para se referir à instância do objeto específico e palavra-chave super
para se referir ao pai.
Aqui está um bom link de controle de acesso básico em Java:
http://java.sun.com/docs /books/tutorial/java/javaOO/accesscontrol.html
Esta você também pode achar útil