Odpowiedź sprowadza się do Java does not support lower bounds on parameterized methods, because such a feature is "not useful enough"
, odnoszą się do similar questionDlaczego kompilator Java nie może prawidłowo dziedziczyć dziedziczenia?
Biorąc pod uwagę następujący fragment:
package demo;
public class Demo {
interface Foo { void foo(); }
interface Bar { void bar(); }
interface FooBar {
<R extends Foo & Bar> R foobar();
static FooBar create() { return new TypicalJavaFooBar(); }
}
private static final class TypicalJavaFooBar implements Foo, Bar, FooBar {
public void bar() { System.out.println("foo"); }
public void foo() { System.out.println("bar"); }
public <R extends Foo & Bar> R foobar() {
return (R) this;
}
}
public static void main(String[] args) {
FooBar x = FooBar.create();
Foo foo = x.foobar();
Bar bar = x.foobar();
x.foobar().foo();
x.foobar().bar();
}
}
bez wyraźnej obsady do R
w TypicalJavaFooBar#foobar
kompilator nie powiedzie się z powodu następującego błędu
Error:(13, 20) java: incompatible types: demo.Demo.TypicalJavaFooBar cannot be converted to R
My pytanie brzmi: dlaczego? Wydaje mi się, że kompilator powinien mieć wystarczającą ilość informacji, ponieważ TypicalJavaFooBar
jest jednoznacznie zdefiniowany do implementacji zarówno Foo
, jak i Bar
; dlaczego nie wystarczy, aby spełnić warunek Foo & Bar
?
UPDATE
Głównym celem tego ćwiczenia jest określenie następującą umowę: wywołanie metody foobar
na instancji FooBar
gwarantuje powrót coś który implementuje zarówno Foo
i Bar
.
@horatius To nie ma nic wspólnego z tym pytaniem. – chrylis
W 'TypicalJavaFooBar' możesz zmienić typ zwracania metody' foobar' na 'TypicalJavaFooBar', co również eliminuje obsadę. Chociaż to nie odpowiada na twoje pytanie, to właśnie bym prawdopodobnie zrobił w tej sytuacji.Chociaż generalnie preferuję kompozycję powyżej dziedziczenia i dlatego raczej nie napotkam tej sytuacji. :-) – Waldheinz
@Andrey, niestety twój "główny cel" nie jest faktycznie możliwy w systemie typu Java. Możesz zwrócić coś, co gwarantuje implementację określonego interfejsu, ale nie możesz wyrazić "czegoś, co implementuje oba te interfejsy". –