Answer boils down to Java does not support lower bounds on parameterized methods, because such a feature is "not useful enough"
, refer to a similar question
Given the following snippet:
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();
}
}
Without the explicit cast to R
in TypicalJavaFooBar#foobar
compiler fails with the following error
Error:(13, 20) java: incompatible types: demo.Demo.TypicalJavaFooBar cannot be converted to R
My question is why? To me, it seems that the compiler should have enough info since TypicalJavaFooBar
is clearly defined to implement both Foo
and Bar
; why isn't that enough to satisfy the Foo & Bar
constraint?
UPDATE
The main goal of this exercise is to define the following contract: calling method foobar
on an instance of a FooBar
is guaranteed to return something that implements both Foo
and Bar
.