这是在网上只看到的一道java关于多态继承的问题,看着很简单,结构出乎意料,也是研究了一天终于搞明白了一点
问题来自:http://blog.itpub.net/28562677/viewspace-1200194/
- public class DispatchTest {
- public static void main(String[] args) {
- Base b = new Sub();
- System.out.println(b.x);
- }
- }
- class Base {
- int x = 10;
- public Base() {
- this.printMessage();
- x = 20;
- }
- public void printMessage() {
- System.out.println("Base.x = " + x);
- }
- }
- class Sub extends Base {
- int x = 30;
- public Sub() {
- this.printMessage();
- x = 40;
- }
- public void printMessage() {
- System.out.println("Sub.x=" + x);
- }
- }
Sub.x=30
20
对于后两个很容易理解,对于第一个 Sub.x=0
首先,
- Base b = new Sub();直接找到子类的构造器,由于子类构造器没有显示的使用super或this,所以隐藏super(),调用父类无参构造器
- 构造器构造器先调用super或this,直到调用到Object类,
- </pre><pre name="code" class="java">然后父类开始实例化对象,执行 int x = 10;
- </pre><pre name="code" class="java">然后父类执行构造器中第一句:
- <pre name="code" class="java">this.printMessage();
- </pre><pre name="code" class="java">this在java里只得是当前对象,即运行时的对象,<span style="color:red;">this</span><span style="color:red;">表示某个类的实例,运行时的某个类的实例。(可以用this.getClass.getName()试一下,取到的是子类对象)</span>
所以调用的是子类中重写的printMessge()法,由于子类构造器还没来的及实例化对象,
输出:Sub.x=0
所以子类类的 x 为 0
父类构造器调用完成后,然后开始实例化子类对象,执行int x = 30;
子类继承父类,会重写父类的属性和方法
往下执行Sub.x=30被打印
多态中,也可以叫父类引用指向子类对象,
子类重写完父类后,方法调用的是子类的方法,属性调用的是父类的属性
另附一个列子说明第三个值:
(转):
java多态中,父类不能引用子类的属性
class Person{ String name = "person"; } class Son extends Person { String name = "son"; } public class Test { public static void main(String[] args){ Person p = new Son(); System.out.println(p.name); } } 结果为person。 为什么不是son?
变量是静态绑定,方法是动态绑定。静态绑定就是变量本身什么类型,就用哪个里面的。例如,你的p.name的p是Person类型,那么name就是Person类中的name。而如果是动态绑定,那么会从本身类型开始向超类型查找。如果name是方法,那么用于p是Son
类的一个对象,所以会从Son开始找name方法,如果找不到再到父类中找。
这下也就很容易理解 b.x=20