我研究过在实例方法的情况下,在运行时jvm使用实际的实例类,在类方法的情况下,编译器只会查看引用变量的声明类型而不是实际的类。
我研究了这个概念实例方法隐藏..
在我的proram中,我使用了接口引用变量来存储类的对象,并尝试使用它来访问类的实例方法,但它引发了错误。 我的计划如下:
interface A
{
void show();
}
class B implements A
{
public void show()
{
System.out.println("Interface Method");
}
void info()
{
System.out.println("IN Info");
}
}
class interDemo
{
public static void main(String args[])
{
A a;
B b=new B();
a=b;
a.show();
a.info();
}
}
请帮助我理解这个概念......
答案 0 :(得分:7)
编译器告诉您类型A
没有定义名为info
的方法。这是正确的:编译器不知道在运行时,a
的类型实际上是B
,它具有info
方法。允许a.info()
调用实际编译并发送到字节码是不安全的,没有什么可以说a
总是类型为B
。
这称为static typing。在Java和其他静态类型语言中,您需要“强制转换”变量以强制编译器将其视为另一种类型。在这种情况下,您可以编写((B) a).info()
。
答案 1 :(得分:1)
sjr是对的。这是另一种看待它的方式:
您指定的A
只能show
。这意味着当你有一个A
引用变量时,就可以做到这一点。
这意味着任何愿意show
的类都可以实现该接口。需要show
对象的客户端可以使用A
而不知道或关心底层类是否有其他方法。这是面向对象编程提供的抽象的一个关键方面。
答案 2 :(得分:1)
您可能希望在YouTube上看到此lecture。它涵盖了你的问题,我希望它能帮助你。
简而言之:a的静态类型是A.在将b分配给a之后,a的动态类型是B.所以此时,静态类型a是A而动态类型是a B.编译器不遵循动态类型,它只检查静态类型。所以它不会让其他任何东西,然后静态类型将允许。
因此,在您的示例中,如果使用静态类型A的引用,则只能从类A调用方法。
答案 3 :(得分:0)
超级概念没有混乱
=====================================
要知道方法将在何处执行的2个规则(当使用超类型引用来调用方法时)
注意:检查“对象创建”/“引用分配”语句以应用规则
1 RULE:首先检查要调用的方法。如果 static / overloaded / single - 那么它就变成了静态多态/ static(编译器查找引用类型) ---因此总是从参考类型执行
2 RULE:检查要调用的方法 - 如果被覆盖 - 那么它就变成动态多态(jvm查找对象类型) ---因此总是从对象类型(即从右到新关键字)执行
例如:
super s=new child();
s.play();
这里有2例:
1st :check play()是静态(静态/重载/单个方法)或动态(重写)
第二名:如果是静态的,它将从超级参考类型执行导致编译时多态性
如果是动态的,它将从子节点执行,即对象类型导致动态多态