Java 子类继承父类成员中的问题
之前搞错了,变量没有“重写”一说,只有方法才能被“重写”。如果我们在子类中声明了一个和父类中一样的变量,那么实际的情况是,子类的内存堆中会有类型和名字都相同的两个变量。
现在考虑一种情况,如下所示,我们在子类中声明一个名字与父类中变量一样,但是类型不同的变量i(一个int,一个double),同时我们在父类中有一个print()打印i,那么当我们从子类的对象中调用这个print()时,他到底会打印哪一个i?
class SuperClass { public int i; SuperClass(){ i=10; System.out.println("SuperClass() is construted."); } public void print(){ System.out.println("the i in SuperClass: "+i); } } class SubClass extends SuperClass { public double i; SubClass(){ i=20.0; System.out.println("SubClass() is constructed."); } public void printSub(){ System.out.println("the i in SubClass: "+i); } } public class TestDemo { public static void main(String[] args) { SubClass sub=new SubClass(); System.out.println("sub.i is: "+sub.i); sub.printSub(); sub.print(); } } 输出结果为: SuperClass() is construted. SubClass() is constructed. sub.i is: 20.0 the i in SubClass: 20.0 the i in SuperClass: 10
我们很清楚,如果在子类中重新声明一个同样的print()函数,父类的print()函数就会被覆盖掉,这时print()输出的是在子类中定义的double i=20.0,所以对这种情况我没有讨论。
从输出结果来看,通过子类SubClass的对象sub访问到的i的值为double i=20.0,然而通过子类对象调用在父类中定义的print(),打印的仍然是父类中的int i=10,如何解释这种情况?
现在我们把SubClass进行修改:
class SubClass extends SuperClass { public int i; SubClass(){ i=20; System.out.println("SubClass() is constructed."); } public void printSub(){ System.out.println("the i in SubClass: "+i); } } /*测试结果为*/ SuperClass() is construted. SubClass() is constructed. sub.i is: 20 the i in SubClass: 20 the i in SuperClass: 10
我们看到,就算是在子类SubClass中声明了一个完全一样的i,通过子类对象调用在父类中定义的print(),打印的仍然是父类中的int i=10。说明了两点:子类仍然含有父类中的i,父类的方法不能操作子类中的变量。
接下来,我再进行改动:
class SubClass extends SuperClass { public int i; SubClass(){ i=20; System.out.println("SubClass() is constructed."); } public void print(){ System.out.println("the i in SubClass: "+i); } } class TestDemo { public static void main(String[] args) { SubClass sub=new SubClass(); System.out.println("sub.i is: "+sub.i); System.out.println("((SuperClass)sub).i is:"+((SuperClass)sub).i); System.out.println("\n sub.print() is :"); sub.print(); System.out.println("((SuperClass)sub).print() :"); ((SuperClass)sub).print(); } } 输出结果: SuperClass() is construted. SubClass() is constructed. sub.i is: 20 ((SuperClass)sub).i is:10 sub.print() is : the i in SubClass: 20 ((SuperClass)sub).print() : the i in SubClass: 20
改动后,子类父类中都有int i,他们的值不同;也都有完全一样的print()来打印i。看看结果,父类的i仍然存在子类的内存中,只是它被”隐藏“起来了,可以通过向上转型访问到。而父类中的print()方法,却访问不到了,被完全覆盖掉了。