문제
죄송합니다. 이것이 상속 문제라고 생각했습니다. 배열 목록 질문이었습니다!
좋아, 내 문제는 내가 생각했던 것보다 더 구체적이다. 그래서 나는 두 가족이 있습니다. 카드와 구역. 영역은 카드를 잡고있는 상자입니다.
Zone, Zonelist 및 Zonemap의 처음 두 개의 서브 클래스는 카드를 저장하는 두 가지 방법입니다. Hand 및 Pokerhand와 같은 추가 서브 클래스는 그들이 저장하는 카드를 다루는 특정 방법을 가지고 있습니다.
복잡한 곳은 카드에도 Pokercard와 같은 서브 클래스가 있으며 Zonelist 및 Zonemap의 서브 클래스는이를 구성하기위한 것입니다.
그래서 Zonelist에서 나는 가지고 있습니다 protected ArrayList<Card> cardBox;
그리고 Pokerhand에서 나는 선언 할 수있을 것으로 예상했다 cardBox = new ArrayList<PokerCard>();
Pokercard는 카드이기 때문에. 내가 얻는 오류는 Arraylist와 관련하여 카드와 갱 private ArrayList<PokerCard> cardBox;
내부 포커 핸드 (Inside Pokerhand)이지만, 그 결과 내 프로그램을 벌리고 숨어있었습니다.
그래서 실제로, 어레이리스트 사이의 캐스팅에 관한 질문은 무엇입니까? Java는 내가 할 수 없다고 말합니다. 어떻게 할 수 있는지에 대한 아이디어가 있습니까?
지.
해결책
내가 당신을 올바르게 이해한다면, 당신은 아마도 다음을 선언해야 할 것입니다.
public class ZoneList<T extends Card> {
protected List<T> cardBox;
}
public class PokerHand extends ZoneList<PokerCard> {
public PokerHand() {
cardBox = new ArrayList<PokerCard>();
}
}
다른 팁
Marc와 Kolstae는 문제를 해결하는 방법에 대한 좋은 답변을했지만 설명 할 가치가 있다고 생각합니다. 왜 원래 코드가 작동하지 않습니다.
문제를 단순화하기 위해 나는 과일 측면에서 문제를 제기하는 경향이 있습니다. 우리가 가지고 있다고 가정합니다.
List<Banana> bananaBunch = new ArrayList<Banana>();
List<Fruit> fruitBowl = bananBunch;
fruitBowl.add(new Apple());
이것이 허용된다면, 우리는 많은 바나나에 사과로 끝납니다. 이것은 분명히 나쁜 것입니다. 그렇다면 문제는 어디에 있습니까? 첫 번째 줄은 괜찮아 야하고 세 번째 줄은 괜찮아 야합니다. 어떤 종류의 과일을 추가 할 수 있습니다. List<Fruit>
- 따라서 문제는 두 번째 줄에 있어야합니다. 이것이 이런 종류의 문제를 피하기 위해 정확하게 금지 된 것입니다.
그것이 전혀 도움이됩니까?
우선, 특히 복잡한 상속을 수행하려는 경우 속성에 직접 액세스하는 것보다 Getter/Setter 방법을 사용하는 것이 일반적으로 더 좋습니다.
제네릭 문제는 슈퍼 클래스 (또는 최상위 인터페이스/초록 클래스)에서 Cardbox getter를 다음과 같이 정의 할 수 있습니다.
protected ArrayList<? extends Card> getCardBox();
이렇게하면 서브 클래스로 그것을 ovverride 할 수 있고 모든 유형의 서브 클래스 목록을 반환 할 수 있습니다.
이를 수행하는 한 가지 방법은 먼저 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);
}
이것은 Access Control이 Arraylist에 무엇이 있는지에 달려 있습니다. Zonelist
. 디버거 진술서에서 나온 나의 가정은 그것이 표시되지 않거나 공개적이거나 보호된다는 것입니다. 서브 클래스는 동일한 이름의 변수를 정의하여 액세스 할 수있는 부모 클래스 변수를 "숨기기"할 수 있습니다. 당신은 또한 사용할 수 있습니다 this
특정 개체 인스턴스를 참조 할 키워드 super
부모를 참조 할 키워드.
Java의 기본 액세스 컨트롤에 대한 좋은 링크는 다음과 같습니다.
http://java.sun.com/docs/books/tutorial/java/javaoo/accesscontrol.html
이것은 또한 도움이 될 수 있습니다