Given any interface I
, it is possible to declare a variable that holds a reference to any object of a class C
that implements I
:
I i = new C();
I want to do something similar. Given two interfaces, I want to declare a variable that holds a reference to any object of a class that implements both interfaces:
interface Foo { void foo(); }
interface Bar { void bar(); }
class Humpty implements Foo, Bar {
public void foo() { System.out.println("Humpty.foo()"); }
public void bar() { System.out.println("Humpty.bar()"); }
}
class Dumpty implements Foo, Bar {
public void foo() { System.out.println("Dumpty.foo()"); }
public void bar() { System.out.println("Dumpty.bar()"); }
}
public class Program {
public static void main(String[] args) {
// I actually have no idea what the syntax should be.
Random random = new Random();
// Fix: I previously used <? extends Foo, Bar>, thanks Jon Skeet and vijucat
<? extends Foo & Bar> foobar;
if (random.nextBoolean())
foobar = new Humpty();
else
foobar = new Dumpty();
foobar.foo();
foobar.bar();
}
}
I have tried the above snippet, but <? extends Foo, Bar>
causes a compilation error. What should the correct syntax be? I would like to know if this is possible in other statically typed JVM languages, too: Scala, Kotlin, Ceylon, etc.
Given two interfaces, I want to declare a variable that holds a reference to any object of a class that implements both interfaces
Unfortunately you can't do that. You can do so for a parameter in a generic method, like this:
public static <T extends Foo & Bar> void someMethod(T value) {
Foo x = value;
Bar y = value;
}
... or you could do likewise for an instance variable in a generic class:
class Test<T extends Foo & Bar> {
private T value;
public Test(T value) {
this.value = value;
}
}
... but you can't declare a variable which needs to just satisfy both of those constraints.
(Note the syntax here for two constraints - it's &
rather than a comma.)
See more on this question at Stackoverflow