日期:2014-05-20  浏览次数:20649 次

子类方法中引用了父类中非同名方法,但该父类引用了该子类同名父类方法(有点绕,第一次发帖)
代码
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()。
------解决方案--------------------
引用:
求解释,为什么陷入死循环!!!!难度super.mb_fun();就是把父类中代码copy下来?

你的代码里的问题主要是这样的:
程序首先初始化了类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(),接下去就不用我说了,一个无限循环。