Вопрос

Извините, я думал, это вопрос о наследстве:все это время это был вопрос ArrayList!

Хорошо, моя проблема более конкретна, чем я думал.Итак, у меня есть две семьи классов.Карты и зоны.Зоны представляют собой ячейки для хранения карт.

Первые два подкласса Zone, ZoneList и ZoneMap предназначены для двух разных способов хранения карт.Дальнейшие подклассы, такие как Hand и PokerHand, имеют свои собственные способы обращения с хранящимися в них картами.

Сложность заключается в том, что у Card также есть подклассы, такие как PokerCard, и что подклассы ZoneList и ZoneMap предназначены для их организации.

Итак, в ZoneList у меня есть protected ArrayList<Card> cardBox; и в PokerHand я ожидал, что смогу объявить cardBox = new ArrayList<PokerCard>(); поскольку PokerCard — это карта.Ошибка, которую я получаю, заключается в том, что я, по-видимому, не могу выполнить преобразование между Card и GangCard, когда дело доходит до ArrayLists...Поэтому я пытался это исправить, просто переобъявив cardBox как private ArrayList<PokerCard> cardBox; внутри PokerHand, но это привело к сокрытию, которое мешало моей программе.

ТАК действительно, вопрос в кастинге между ArrayLists?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> - значит, проблема должна быть во второй линии.Это то, что запрещено, именно во избежание подобных проблем.

Это вообще помогает?

Прежде всего, обычно лучше использовать методы получения/установки, чем прямой доступ к свойствам, особенно если вам предстоит выполнять много сложного наследования.

Что касается проблемы с дженериками, вы можете попробовать определить метод получения cardBox в суперклассе (или интерфейсе верхнего уровня/абстрактном классе) как:

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);
}

Это будет зависеть от того, какой контроль доступа установлен в Arraylist в Zonelist.Исходя из оператора отладчика, я предполагаю, что он либо не помечен, либо общедоступен, либо защищен.Подкласс может «скрыть» переменную родительского класса, к которой у него есть доступ, определив переменную с тем же именем.Вы также можете использовать this ключевое слово для ссылки на конкретный экземпляр объекта и super ключевое слово для ссылки на родителя.

Вот хорошая ссылка на базовый контроль доступа в Java:

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

Это также может оказаться вам полезным

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top