假设,子类重载父类的方法,并将子类的成员覆盖。
创建子类对象实例,将其上转型成父类。
例子1
public class Parent {
public void init() {
System.out.println("1 init parent");
this.demo();
}
public void demo() {
System.out.println("2 demo parent");
}
}
public class Son extends Parent {
public void init(){
super.init();
System.out.println("3 init son");
this.demo();
}
public void demo() {
System.out.println("4 demo Son");
}
public static void main(String[] args) {
//Parent p = new Son();//1
Son son = new Son();//2
son.init(); // init(son)
}
}
当执行1时结果为:
1 init parent
4 demo Son
3 init son
4 demo Son
当执行2时结果为:
1 init parent
4 demo Son
3 init son
4 demo Son
情况1和情况2其实是相似的,由于使用new Son()创建实例,上转型之后,访问的也是子类重载的方法而Parent中的init()方法中的this也被认为是指向堆区域中son的实例化对象,故this.demo()访问的仍然是子类中重载的方法。
例子2
public class Parent {
public String name="tom";
public void init() {
System.out.println(this.name);
}
}
public class Son extends Parent {
public String name="jack";
public void init(){
super.init();
System.out.println(this.name);
}
public static void main(String[] args) {
//1 当前运行类 Son
Son son = new Son();
son.init(); //init(son)
System.out.println("## " + son.name);
//2 当前运行类Parent
Parent p = new Son();
p.init();
System.out.println("** " + p.name);
}
}
当代码运行1时 我猜测结果应该是:
jack
jack
##jack
但实际结果却是:
tom
jack
## jack
此时Parent类中this.name指向的是父类中的name值
只有几种情况可以解释这种结果
1.this并不指向son在堆中创建的实例
2.创建对象时内存中使用了其他机制来保证这种结果的生成。
翻看了一下《深入理解Java虚拟机 JVM高级特性与最佳实践》这本书 似乎得出了一些端倪
由此可见当访问成员变量时,检测到父类的成员变量之后程序停止继续寻找。
对于方法,由于其内容存放在方法区内,每个对象的发放应该是通过其自身的this即引用唯一绑定。故就差不多解释的通了。
《深入理解Java虚拟机 JVM高级特性与最佳实践》一书的下载地址:
http://www.jb51.net/books/163531.html#down
上面只是个人的一点点猜测 ,不吝赐教。