有一个名为
的方法的接口 foo(boolean arg1, String arg2);
此外,我有两个实现此方法的类。现在,当我从接口调用foo方法时,它如何决定选择哪种实现?
这两个实现采用相同的参数并返回相同的对象,但是实现不同。
答案 0 :(得分:4)
致电时
a.foo(b, c);
它查看a
所指向的对象的类型,而不是引用的类型,并调用该类型实现的方法。
最初,它使用一个虚拟查找表,您可以对其进行映像处理,因此价格昂贵,因此在Oracle / OpenJDK JVM中,它可以根据使用情况动态内联多达两个虚拟方法,因此看起来更像这样。
if (a instanceof Type1) {
((Type1) a).foo(b, c);
} else (a instanceof Type2) {
((Type2) a).foo(b, c);
} else {
a.foo(b, c); // do a full vtable lookup.
}
答案 1 :(得分:3)
您不能在接口上调用方法...您需要在一个对象(实现您的接口的类的实例)上调用它们。这就是被调用的代码。
答案 2 :(得分:0)
我相信您询问有关在其他(默认)接口方法中使用接口方法的问题。
方法将基于接口变量引用的实例进行选择。这是一个小例子
class Scratch {
public static void main(String[] args) {
ClassA varClassA = new ClassA();
ClassB varClassB = new ClassB();
Bar interfaceVar = varClassA;
interfaceVar.foo("firstCall");
interfaceVar = varClassB;
interfaceVar.foo("secondCall");
varClassA.foo("call from A");
varClassB.foo("call from B");
interfaceVar = new Bar() { // or just interfaceVar = System.out::println
@Override
public void printParam(String params) {
System.out.printf("Anonimus class: %s%n", params);
}
};
interfaceVar.foo("Anonimus call");
}
public interface Bar {
default void foo(String param) {
printParam(param);
}
void printParam(String params);
}
public static class ClassA implements Bar {
@Override
public void printParam(String params) {
System.out.println(String.format(
"Called from %s wth params: %s",
this.getClass().getName(),
params)
);
}
}
public static class ClassB implements Bar {
@Override
public void printParam(String params) {
System.out.printf("param from ClassB:%s%n", params);
}
}
}
输出:
Called from Scratch$ClassA wth params: firstCall
param from ClassB:secondCall
Called from Scratch$ClassA wth params: call from A
param from ClassB:call from B
Anonimus class: Anonimus call
Process finished with exit code 0