子类方法中引用了父类中非同名方法,但该父类引用了该子类同名父类方法(有点绕,第一次发帖)
代码
package ydZh;
class J_SuperClass
{
void mb_method(){
System.out.println("J_SuperClass::mb_method");
}
void mb_fun(){
System.out.println("J_SuperClass::mb_fun");
this.mb_method();
}
}
class J_SubClass extends J_SuperClass
{
void mb_method(){
System.out.println("J_SubClass::mb_method: Begin");
super.mb_fun();
System.out.println("J_SubClass::mb_method: End");
}
}
public class J_Test
{ public static void main(String[] args)
{
J_SubClass a = new J_SubClass();
a.mb_method();
}
}
第一次发帖,不知道有什么规矩,多多包涵!!!!
------解决方案--------------------如果你对死循环有疑问,你是不是觉得: J_SuperClass的mb_fun()方法中
this.mb_method();应该是调用J_SuperClass的mb_method(),而不是J_SubClass的mb_method(),是吧??
这里最主要的,其实就是this关键字。this指向的总是
new 后面的那个类对象!也就是这里的:J_SubClass。
所以就很好理解,为什么会死循环了。因为:this.mb_method()调用的是J_SubClass里的mb_method()。
------解决方案--------------------
你的代码里的问题主要是这样的:
程序首先初始化了类J_Test,然后调用了里面的main方法,通过指令new在堆中创建了一个J_SubClass类型
的对象,并初始化为默认值,并把这个对象的引用压入main方法的操作数栈,在存到main方便的局部变量
表中的索引0处。然后是调用方便mb_method(),用的字节码指令是invokevirtual(这个指令会按照引用的
对象的实际类型来调用方法),在调用之前把对象的引用从局部变更中取出,压入到mb_method()方便的操
作数栈,在到这个方法的局部变量表的索引0,在调用这个方法时选打印出了“J_subclass::mb_method:Begin"
字符串,然后是对过super关键字调用了父类的方法,这个时候调用方法用到的字节码指令是invokespecial。
这个指令会按照对象的引用类型调用方法,调用方法mb_fun()之前会把对象的引用压入到此方法的操作数栈,但是引时的引用类型是J_superclass,这个是通过对象引用找到的。所以super.mb_fun()方法会去调用类J_superClass中的mb_fun()方法,然后打出了字符串“J_sperclass::mb_fun",然后在这个方法中又调用了
this.mb_method(),其实这个this不用写,他指的就是方法mb_method()局部变量表索引0处的对象引用,关于你和程序为什么
会是个无限循环,关键的原因就是在这里,因为调用mb_method()方法的字节码指令是invokevirtual,
而在方法mb_method()局部变量表中对象的引用类型是J_superclass,
但是这个对象的实际类型是J_subclass,所以用invokevirtual调用的mb_method()
指向了J_subclass中的mb_method(),接下去就不用我说了,一个无限循环。