To nie jest pytanie JavaFX, ale próbuję napisać interfejs w JavaFX, który deklaruje, że klasa jest widoczna. Widoczne klasy mają mieć metodę view(), która zwraca obiekt Node reprezentujący to, co można zobaczyć. Prosty do tej pory, ale tutaj jest, gdzie się komplikuje. Zwrócony węzeł powinien mieć zagwarantowaną metodę getViewable() zwracającą obiekt, który można obejrzeć. Jak to zrobić? Moim pierwszym odruchem było spróbować czegoś takiego:Egzekwowanie wielu ogólnych ograniczeń w języku Java Zwróć typ
interface Viewable<V extends Viewable<V>>{
<N extends Node&View<V>>N view();
}
interface View<V extends Viewable<V>>{
V getViewable();
}
które na pierwszy pojawia się dźwięk i pozwala klasy jak następuje:
class ViewableObject implements Viewable<ViewableObject>{
@Override public ObjectView view(){
return new ObjectView();
}
class ObjectView extends Pane implements View<ViewableObject>{
@Override public ViewableObject getViewable(){
return ViewableObject.this;
}
}
}
Jednak z jakiegoś powodu, ta klasa zestawia również:
class ViewableObject implements Viewable<ViewableObject>{
@Override public Pane view(){
return new Pane();
}
}
Okienko jest węzłem, ale nie implementuje widoku, więc dlaczego ta klasa się kompiluje? Myślę, że to narusza kontrakt metody view(). Nawet nieznajomy, ta sama klasa nie kompiluje się, gdy Pane jest zastąpiony Obiektem:
class ViewableObject implements Viewable<ViewableObject>{
@Override public Object view(){//complains this is not an @Override
return new Object();
}
}
Co tu się dzieje? Czy moja wiedza na temat generyków jest wadliwa? Jak mogę sprawić, aby działało zgodnie z zamierzeniami?
wszystko w imię zgodności wstecznej z kodem generycznym. ale moja lektura [spec] (http://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.4.5) wydaje się nie zgadzać z kompilatorem. w każdym razie może to być bezpieczne, pod warunkiem, że programista wypełnia umowy pozapasmowe, które nie są wyrażone w systemie typu. w tym przypadku zwracanie podtypu okienka implementującego widok – ZhongYu