作者:金良(golden1314521@gmail.com) csdn博客:http://blog.csdn.net/u012176591
一个关于java继承的问题,觉得这是很多初学java者应该注意的问题。
先看下面的代码:
package jinliang; public abstract class Parent { int i=1; public void printI() { System.out.println("i="+i); } } public class Child extends Parent{ int i=2; } public class Main { public static void main(String[] args) { Child childObj=new Child(); childObj.printI(); } }
执行上边的程序,你猜控制台打印的结果是什么?
如果你理所当然地认为打印1,那么你就可以飞过了;如果你对这个打印结果感到很惊讶(因为实际打印结果是2),就继续往下看:
1、为什么打印的是父类属性的原因——执行过程跟踪
(1)调用子类的构造方法前,Java虚拟机隐含地调用父类的构造方法,实例化一个Parent对象,Parent对象的成员被初始化。
(2)Parent对象初始化后,虚拟机在父类对象的基础上,增加子类的属性,例子中增加了子类属性int i=2。注意父类属性int i=1并未消失,只是在派生类这一层被屏蔽了。
(3)由于Parent对象的成员方法printI()未被屏蔽,而且子类没有重写父类方法,所以只能调用的父类对象的printI()成员方法,父类对象的成员方法当然是访问父类对象的成员变量了。
2、super关键字
super关键字在java中的作用是使被屏蔽的成员变量或者成员方法或变为可见,或者说用来引用被屏蔽的成员变量和成员成员方法。super是用在子类中,目的是访问直接父类中被屏蔽的成员。
上面的代码也可以这样写:
package jinliang; public abstract class Parent { int i=1; public void printI() { System.out.println("i="+i); } } public class Child extends Parent{ int i=2; public void printI() { super.printI(); } } public class Main { public static void main(String[] args) { Child childObj=new Child(); childObj.printI(); } }
3.怎么才能打印子类的成员变量
在子类中重写父类方法,重写的成员方法当然优先调用子类的成员变量。
派生类的方法覆盖了基类的方法,基类的方法对派生类来说为不可见(像作用域),也就是派生类里的同名方法重新写了基类的同名方法。
下面的程序将打印出子类对象的成员变量的值:
package jinliang; public abstract class Parent { int i=1; public void printI() { System.out.println("i="+i); } } public class Child extends Parent{ int i=2; public void printI() {//对父类方法进行重写,形成子类的成员方法 System.out.println("i="+i); } } public class Main { public static void main(String[] args) { Child childObj=new Child(); childObj.printI(); } }
4.将以上三个例子中main()方法中的对象创建语句Child childObj=new Child();修改为Parent childObj=new Child();执行结果与修改前完全相同。