Список <A>, ссылающийся на Список <подкласс-о-А> - PullRequest
3 голосов
/ 26 июля 2011

Если у меня есть класс А, который содержит список детей с классом А, например

public Class A
{
    protected List<A> children = new ArrayList<A>();
    ...
}

Возможно ли в подклассе B иметь своих собственных потомков другого класса C и создать ссылку на список детей в классе A? Класс A имеет методы, которые хотят использовать другие классы, например, отправить своих детей в. Однако класс A является общим классом, а B и C более конкретны. Поэтому, чтобы упростить чтение кода и избежать большого количества типов, я бы хотел, чтобы список суперкласса ссылался на список подклассов.

Поэтому, когда я обновляю otherChildren , список children также будет обновляться. Я хотел бы сделать что-то, как в примере ниже, но это не работает, и это не может быть приведено либо (children = (List ) otherChildren) .

Но есть ли способ достичь этого? Я действительно хотел бы избежать всех типов, которые я получу иначе.

public Class B extends A
{
    private List<C> otherChildren = new ArrayList<C>();

    public B()
    {
        children = otherChildren;
        ...
        // Modification of otherChildren will result in the same
        // modification in children
    }
}

public Class C extends A
{
     ...
}

Ответы [ 3 ]

3 голосов
/ 26 июля 2011

Вы не можете сделать это, потому что они разных типов. Одна из операций, которую вы можете выполнить с экземпляром List<A>, - добавить произвольный экземпляр A; Вы не можете сделать это на List<C>, потому что это более ограниченный тип.

Исправлено так, что A принимает параметр типа:

public class A <T extends A> {
    protected List<T> children = new ArrayList<T>();
    // ...
}

public class B extends A<C> {
    private List<C> otherChildren = new ArrayList<C>();
    public B() {
        children = otherChildren;
    }
    // ...
}

public class C extends A<? extends A> {
    // Or some such
}

Конечно, в этот момент вы также можете сказать, что вам вообще не нужен otherChildren. Вы можете работать непосредственно с children в подклассе, и он все равно будет работать без явных приведений.

2 голосов
/ 26 июля 2011

Все, что вам нужно сделать, это изменить объявление детей в классе A на:

protected List<? extends A> children = new ArrayList<A>();
2 голосов
/ 26 июля 2011

Заставляя детей ссылаться на otherChildren, вы пытаетесь дать A представление о List<C> как List<A>, A затем может разумно ожидать добавления объекта A к тому, что он считает списком As, нона самом деле предполагается, что это коллекция Cs.

Концептуально это недопустимо.

Если это присваивание допустимо, то, вероятно, в C ваши другиеChildren должны быть объявлены как List<A>.В связи с этим возникает вопрос: почему вы не можете использовать массив children напрямую?

edited:

Я думаю, вам нужен более сложный A, возможно, с использованием обобщений с параметром "extends"Так что у A нет списка As, но есть список вещей, которые расширяют As.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...