2009-03-29 2 views
4

Учитывая иерархию классов, где базовый класс определяет рекурсивный сам-тип:Тип поля Java для значения рекурсивного типичного типа?

abstract class A<T extends A<T>> { } 

Как можно объявить еще один класс (который не должен быть универсальным в Т, потому что такой Т может изменяться в течение времени жизни объект) с полем, которое может содержать любой подкласс A?

Следующие не работает:

public class B { 
    //fails to compile, because the capture of ? is not sufficiently narrow 
    private A<?> a; 

    public <T extends A<T>> setA(T a) { 
     this.a = a; 
    } 
} 

- КОНЕЦ ВОПРОСА -

Я заметил тенденцию ряда членов StackOverflow подойти некоторые сложные вопросы с «почему ты это в первую очередь? " Следующее является оправданием моего использования этого шаблона - вы можете заметить, что стандартная библиотека Java также использует в своем определении класса Enum рекурсивные самонастройки: Enum<E extends Enum<E>>. Этот вопрос может быть подобным образом спросил «как определить поле типа Enum<?>

Обоснование Пример:.

abstract class A<T extends A<T>> { 
    public abtract T self(); 
    public B<T> bify(Bifyer bifyer) { 
     return bifyer.bify(self()); 
    } 
} 

с подклассов:

class ASub1 extends A<ASub1> { 
    public ASub1 self() { return this; } 
}  

class ASub2 extends A<ASub2> { 
    public ASub2 self() { return this; } 
}  

привязан к иерархии параллельного класса:

abstract class B<T extends A<T>> { 
} 

class BSub1<T extends A<T>> implements B<T> { } 
class BSub2<T extends A<T>> implements B<T> { } 
//and others 

И с генерацией экземпляров B, управляемых исполнителями необлученные монокристаллы разорийны тировка интерфейса Bifyer:

interface Bifyer { 
    B<ASub1> bify(ASub1 asub1); 
    B<ASub2> bify(ASub2 asub2);   
} 

Реализации этого интерфейса может возвращать BSub1 или BSub2 для B. Это, по существу, применение шаблона для посетителей, где Bifyer является посетителем, но в отличии от стандартного Visitor акцепта метод возвращает значение вместо void. Это обеспечивает модульную структуру, в которой могут быть указаны различные реализации Bifyer для обеспечения альтернативного поведения и типов возврата для метода Bify. Например, для каждого подкласса B.

+0

Там нет оснований использовать связанный '>' вместо просто '' newacct

ответ

4

Если вы связали подстановочный знак ? ниже на A, он должен работать:

public class B { 
    private A<? extends A> a; 

    public <T extends A<T>> void setA(T a) { 
     this.a = a; 
    } 
} 
+0

Ах, спасибо! Я попытался A > но и другие перестановки, но этого мне не приходило! –

Смежные вопросы