Generic extends Generic

Network

Top Contributor
Hi,

ich habe ein kleines logisches Problem mit Generics.
Wie löse ich folgende Problemstellung:
Java:
public class AbstractClass<A extends AbstractClass> implements AbstractInterface<A> {
     public A getAnotherClass() {
          return new AnotherClass<A>();
     }
}
In diesem Beispiel muss die Klasse welche selbst der Vererber des generischen Typ ist wissen, welcher generische Typ verwendet wird um die entsprechenden Methoden bereitzustellen.
Der Compiler gibt zurecht die Fehlermeldung, dass
Java:
A extends AbstractClass
wiederum eine generische Typzuweisung benötigt. Das ist natürlich nicht möglich denn das würde dann so ausarten: <A<A<A<A<A<A<A ... etc....

Übersehe ich hier irgendetwas oder ist diese Form der Verwendung von Generics schlicht nicht möglich?

Vielen Dank
Gruß
Network
 
wenn du in getAnotherClass() ein Objekt AnotherClass<A> erzeugst, wieso gibst du dann nicht AnotherClass<A> zurück, sondern A?
weil AbstractInterface das so vorgibt?
mit 'A extends AbstractClass' ist überhaupt nicht festgelegt, dass A etwas mit AnotherClass zu tun hat,
das ist bisher alles reichlich lose

wie es zu <A<A<A<A<A<A<A kommt sehe ich vorerst nicht

ein Objekt der Klasse A zu erzeugen ist wie immer recht schwierig,
ein bekanntes AnotherClass wäre dazu hilfreich

eine kompilerfehlerfreie Kombination ist:
Java:
class AbstractClass<A extends AbstractClass>  implements AbstractInterface<A> {
    public AnotherClass<A> getAnotherClass()  {
        return new AnotherClass<A>();
    }
}

interface AbstractInterface<T> {
    public AnotherClass<T> getAnotherClass();
}

class AnotherClass<T> { }
 
Vielleicht ging es um die Warning, die bei
class AbstractClass<A extends AbstractClass> implements AbstractInterface<A> {
vs.
class AbstractClass<A extends AbstractClass<A>> implements AbstractInterface<A> {
entsteht?
 
Vielleicht ging es um die Warning, die bei
class AbstractClass<A extends AbstractClass> implements AbstractInterface<A> {
vs.
class AbstractClass<A extends AbstractClass<A>> implements AbstractInterface<A> {
entsteht?

Ganz genau und zufällig habe ich das Thema nochmals in einem Buch gefunden, dass man es genauso schreiben muss:
Java:
class AbstractClass<A extends AbstractClass<A>>
Und warum. Ein sehr komisches Konstrukt wie ich "fande".
Dabei hat mir der Compiler aber nicht gerade geholfen gehabt, er hatte sogar noch mehr Verwirrung dazu gegegeben, weil er 'anfehlerte' das AbstractClass nicht von AbstractClass extended und damit kein gültiger Typ A ist.
Was zwar richtig ist aber in jedem anderen Zusammenhang akzeptiert werden würde, deshalb erschienen mir eure Beiden genannte Lösung nicht schlüssig.

Ich bedanke mich
Gruß
Net
 
welche Fehlermeldung ist das genau?
hängt vielleicht auch mit den weiteren Konstrukten, Bedingungen durch das Interface, zusammen,
bei mir gibts eher nur eine allgemeine 'raw type'-warning

AbstractClass<A extends AbstractClass>
oder
AbstractClass<A extends AbstractClass<A>>
macht schon ein wenig inhaltlichen Unterschied, soll die Parameter Klasse direkt eine 'eigene AbstractClass' sein oder nicht?

Java:
class C extends AbstractClass { }
class B extends AbstractClass<C> { } // *
class D extends AbstractClass<D> { }
class E extends D { }
class F extends AbstractClass<D> { }
class G extends AbstractClass<E> { } // *
mit 'AbstractClass<A extends AbstractClass<A>>' gibt es in zwei *-Fällen Probleme,
der erste nur allgemein weil ein generischer Typ erwartet wird,
der zweite ist schon interessanter:
E ist zwar letztlich auch eine AbstractClass, aber keine 'eigene', keine AbstractClass<E>, sondern eine AbstractClass<D>
 
Hmja, diese Selbstreferentiellen Generics sind so eine Sache ... Bei "Comparable" sieht's so einfach aus, aber gelegentlich habe ich versucht, sie ernsthaft einzusetzen, und irgendwie landet man doch immer in der Hölle. Manchmal kann der getThis-Trick helfen, manchmal hilft es, wenn man den Typ "grobranularer" festlegt (also nicht die Typen der generics-Parameter festzulegen versucht, sondern des Typs selbst, der die Parameter hat), manchmal kann man mit statischen Typ-Capture-Helper-Methoden wie
Java:
static void <S, T extends S> helper(Type<S, T> type) { ... }
tricksen, aber kompliziert ist es immer...
 

Zurück
Oben