Java中的继承:为什么强制转换变量访问的解析方式与强制转换方法调用的解析方式不同
当涉及到强制转换时,继承是如何工作的(在Java中)?Casting与实例变量一样工作,但与方法不同 给定以下代码;类Java中的继承:为什么强制转换变量访问的解析方式与强制转换方法调用的解析方式不同,java,inheritance,methods,casting,overloading,Java,Inheritance,Methods,Casting,Overloading,当涉及到强制转换时,继承是如何工作的(在Java中)?Casting与实例变量一样工作,但与方法不同 给定以下代码;类C中的注释指的是编译器完成的解析,可以通过查看字节码来检查 A类{ 字符串名; void test1(){ System.out.println(“ATest1=“+this”); } void test2(){ System.out.println(“ATest2=“+this”); } } B类扩展了A类{ 字符串名; void test1(){ System.out.pri
C
中的注释指的是编译器完成的解析,可以通过查看字节码来检查
A类{
字符串名;
void test1(){
System.out.println(“ATest1=“+this”);
}
void test2(){
System.out.println(“ATest2=“+this”);
}
}
B类扩展了A类{
字符串名;
void test1(){
System.out.println(“BTest1=“+this”);
}
void test3(){
System.out.println(“BTest3=“+this”);
}
}
C类{
静态公共void main(字符串…参数){
B=新的B();
b、 name=“Peter”//字段b.name
((A)b).name=“Petra”//字段A.name
System.out.println(b.name);
System.out.println(((A)b).name);
b、 test1();//方法b.test1(b)
((A)b.test1();//方法A.test1(b)
b、 test3();//方法b.test3(b)
b、 test2();//方法b.test2(b)
}
}
您可以使用casting在实例b
中设置name
,并在其附带的“虚拟”对象(可以说是类A
的实例)中设置name
但是,如果涉及方法,则调用总是解析为类b
中的实例b
调用test1
。尽管在((A)b)中调用了.test1()
方法A.test1(b)
(从JVM的角度来看)
我不懂语义。你能帮忙吗
我的猜测是
((A)b).test1()
确认类A
中存在方法test1
。尽管如此,类B
在调用方法时是方法解析的起点,因为((A)B).getClass()==>类B
。但为什么选角被“忽略”?您是否有指向Java语言规范的指针?我不知道去哪里找。您可能会被两个名为name
的变量弄糊涂。您应该删除字符串名称代码>从类B
,然后您将获得正确的行为。在任何情况下,强制转换都“应该”被忽略——这就是方法重写的全部要点。Java中没有继承或重写像name
这样的字段。这是两个不同的变量,它们共享相同的名称。在Java语言中,对于类B
,您可以使用super
访问变量,例如super.name=Petra
和this.name=Peter
。您有两个实例变量(字段),都命名为name
。您只有一个名为test1
的方法。在类B
中重写了相同的方法。因此,无论您是否强制转换,都会调用相同的方法。阅读如何调用虚拟方法(Java中的方法是虚拟的);非常感谢你的推荐。但答案并不像我希望的那样具体。通过对字节码的研究,我们发现铸造的结果与预期一致。看起来这是造成意外行为的原因;我需要对此进行研究。的JVM规范在第3段的“描述”下说,该方法是针对invokevirtual的参数类选择的,在我的示例类B
的实例B
中。((A)b).test1()
中的强制转换要求方法test1()
在编译时存在,但在运行时未选择该方法。这就是我恼火的地方。感谢您的支持。您可能会对名为name
的两个变量感到困惑。您应该删除字符串名称代码>从类B
,然后您将获得正确的行为。在任何情况下,强制转换都“应该”被忽略——这就是方法重写的全部要点。Java中没有继承或重写像name
这样的字段。这是两个不同的变量,它们共享相同的名称。在Java语言中,对于类B
,您可以使用super
访问变量,例如super.name=Petra
和this.name=Peter
。您有两个实例变量(字段),都命名为name
。您只有一个名为test1
的方法。在类B
中重写了相同的方法。因此,无论您是否强制转换,都会调用相同的方法。阅读如何调用虚拟方法(Java中的方法是虚拟的);非常感谢你的推荐。但答案并不像我希望的那样具体。通过对字节码的研究,我们发现铸造的结果与预期一致。看起来这是造成意外行为的原因;我需要对此进行研究。的JVM规范在第3段的“描述”下说,该方法是针对invokevirtual的参数类选择的,在我的示例类B
的实例B
中。((A)b).test1()
中的强制转换要求方法test1()
在编译时存在,但在运行时未选择该方法。这就是我恼火的地方。谢谢你的支持。