Ja, das ist möglich (sozusagen; siehe unten). (In der C++-Welt nennt man dies die " Seltsam wiederkehrende Schablonenmuster ", aber das gilt auch für Java):
public interface Recur<T extends Recur<T>> {
// ...
}
(Beachten Sie die zweite Erwähnung von T
. Das ist ein wesentlicher Bestandteil des CRTP).
Außerdem ist dies der Weg java.util.Enum
definiert ist, so dass ein Enum-Typ namens Foo
muss sich ergeben aus Enum<Foo>
Es handelt sich also auch in Java nicht um ein ungewöhnliches Muster.
Ich würde gerne sagen, dass das oben Gesagte das Ende der Geschichte ist, aber tangens weist in seiner Überarbeitung zu Recht darauf hin, dass es nicht ganz robust ist und sich eigentlich nicht so sehr von seiner Antwort unterscheidet.
Es gibt einen Unterschied (soweit ich weiß) zwischen der Recur<T>
Lösung, die ich habe, und die Recur<?>
Lösung, die Tangens hat:
public interface Recur<T extends Recur<T>> {
T foo();
}
class A implements Recur<B> {
@Override
public B foo() {
return new B();
}
}
class B implements Recur<A> {
@Override
public A foo() {
return new A();
}
}
Mit <T>
würde das obige Beispiel nicht kompilieren; mit <?>
würde es. Aber das ist nur Haarspalterei; es ändert nichts an tangens' zentralem Punkt, der darin besteht, dass angesichts einer bereits gültigen Recur
Implementierung können Sie dafür sorgen, dass nachfolgende Implementierungen den bereits gültigen Typ und nicht sich selbst verwenden. Ich sage immer noch, dass das etwas wert ist, aber es ist nicht mehr wert als die Antwort von tangens.
Abschließend möchte ich Sie bitten, auch die Antwort von tangens hochzustufen, wenn Sie können. (tangens, du solltest deinen Beitrag anfassen, damit ich dich auch hochstufen kann.) Sie haben ein sehr gutes Argument, und es tut mir leid, dass ich es beim ersten Mal übersehen habe. Danke, tangens!