请看如下“变态”的类spa
ParentChildTest.Java示例 对象
public class ParentChildTest {blog
public static void main(String[] args) {继承
Parent parent=new Parent();开发
parent.printValue();博客
Child child=new Child();class
child.printValue();变量
parent=child;语法
parent.printValue();引用
parent.myValue++;
parent.printValue();
((Child)parent).myValue++;//
parent.printValue();
}
}
class Parent{
public int myValue=100;
public void printValue() {
System.out.println("Parent.printValue(),myValue="+myValue);
}
}
class Child extends Parent{
public int myValue=200;
public void printValue() {
System.out.println("Child.printValue(),myValue="+myValue);
}
}
1. 程序运行结果是什么? 2. 你如何解释会获得这样的输出? 3. 计算机是不会出错的,之因此获得这样的运行结果也是有缘由的,那么从这些运行结果中,你能总结出Java的哪些语法特性?
程序运行结果:
解释:
父类对象被定义成子类类型(家族的具体化)
既然子类继承父类,因此子类更能表明这一个家族的具体表现,一个父类的对象被定义成子类类型时就具备了父类的属性和方法。
反过来子类对象不能被定义成父类类型
子类对象为何不能被定义成父类类型呢?由于子类继承于父类,所以子类拥有的方法极可能比父类多,由于除了继承自父类的所有属性和方法外,子类有可能定义了其余的方法,因此大致上看子类的量级要比父类大,因此父类对象能够定义成子类对象,由于多出来的方法能够直接使用子类的,而反过来的话就不行了,由于子类对象不知道如何砍掉那些多出来的方法。
因此,一句话就是小盒子(父类对象)能够套进大盒子(子类)里,大盒子(子类对象)不能套进小盒子(父类)里。
同理,父类对象能够被子类对象赋值(被定义成子类类型),子类对象不能被父类对象赋值。
父类对象只有当明确转换为子类对象时才能够直接控制对象中的属性,只是经过赋值来使父类对象变成子类类型的办法不能使父类对象彻底控制对象中的属性。
若是子类与父类有相同的字段,则子类中的字段会代替或隐藏父类的字段,子类方法中访问的是子类中的字段(而不是父类中的字段)。
换言之,一旦子类父类具备相同名称的字段,就会使继承的状况变得复杂,子类中的父类同名变量或方法就会褪色而不易被调用。
好比,父类子类都有名为F的属性或方法,那么在继承时,子类就会有两个F属性或方法,一个继承于父类(由父类定义),而另外一个由子类本身定义。生成一个子类对象时,子类对象一旦调用F属性或执行F方法就会优先使用子类本身的F属性或执行子类本身的F方法,若是要强行使用父类的F属性或执行父类F方法,得在子类定义中使用super.F()来调用。
总结:(1)当子类与父类拥有同样的方法,而且让一个父类变量引用一个子类对象时,到底调用哪一个方法,由对象本身的“真实”类型所决定,这就是说:对象是子类型的,它就调用子类型的方法,是父类型的,它就调用父类型的方法。
这个特性实际上就是面向对象“多态”特性的具体表现。
(2)若是子类与父类有相同的字段,则子类中的字段会代替或隐藏父类的字段,子类方法中访问的是子类中的字段(而不是父类中的字段)。若是子类方法确实想访问父类中被隐藏的同名字段,能够用super关键字来访问它。若是子类被看成父类使用,则经过子类访问的字段是父类的!牢记:(验证结论发博客) 在实际开发中,要避免在子类中定义与父类同名的字段。不要自找麻烦!——但考试除外,考试中出这种题仍是能够的。