请在下面找到解释该问题的代码片段。
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
I ref = new B();
ref.equals("");
}
}
interface I{
}
class A {
public void method(){
}
}
class B extends A implements I{
}
请参考main()
,ref.equals()
是允许的,但不允许ref.method()
。为什么会这样?
编辑:对象是 B(或 A 或任何其他类)的超类,但同样,A 也是 B 的超类。我的问题是为什么 A 的"method()"在"ref"中不可见,即为什么允许 ref.equals() 但不允许 ref.method()?此方法可见性检查是如何完成的?它是否植根于JVM?
因为你确实将其声明为 I:
I ref = new B();
您只会看到 I and the methods from Object
中声明的方法。
当您执行以下操作时:
将其声明为 A:
A ref = new B();
或将其声明为 B
B ref = new B();
或将其投射到 A
I ref = new B();
((A)ref).method()
您将可以访问:
ref.method()
为了完整起见,如果您想查看 A 和 I 中的方法,您可以在它们之间投射您的对象。或者也有 A 实现 I。
Java 语言规范指出 java.lang.Object 是所有没有任何超接口的接口的直接超类型。
当您使用其接口引用对象时,例如
I ref = new B();
然后,您只能访问接口和 Object 类方法。在将对象强制转换为其类之前,您不会看到类方法。
如果要访问类中声明A
method
,则可以执行以下操作之一:
I ref = new B();
((A)ref).method()
或
A ref = new B();
ref.method();
或
B ref = new B();
ref.method();
接口类型只能使用具体类来实例化,默认情况下,该类是 Object 的子类。因此,您可以在接口类型上调用 Object 中的方法。只有在接口类型或其超级接口中声明了所有其他自定义方法时,才能在该接口类型上调用这些方法。
如果通过接口引用对象,则只能访问接口公开的方法。
使用ref.equals()
equals()
因为它是对象的方法并且可用于所有子类(甚至B,因为B隐式扩展Object
)。
如果 method() 不在 B 中,则在语句I i = new B()
时无法访问它。