转发一道java基础题(多态)

这是在网上只看到的一道java关于多态继承的问题,看着很简单,结构出乎意料,也是研究了一天终于搞明白了一点


问题来自:http://blog.itpub.net/28562677/viewspace-1200194/


[java]  view plain  copy
  1. public class DispatchTest {  
  2.     public static void main(String[] args) {  
  3.         Base b = new Sub();  
  4.         System.out.println(b.x);  
  5.     }  
  6. }  
  7.   
  8. class Base {  
  9.   
  10.     int x = 10;  
  11.   
  12.     public Base() {  
  13.         this.printMessage();  
  14.         x = 20;  
  15.     }  
  16.   
  17.     public void printMessage() {  
  18.         System.out.println("Base.x = " + x);  
  19.     }  
  20. }  
  21.   
  22. class Sub extends Base {  
  23.   
  24.     int x = 30;  
  25.   
  26.     public Sub() {  
  27.         this.printMessage();  
  28.         x = 40;  
  29.     }  
  30.   
  31.     public void printMessage() {  
  32.         System.out.println("Sub.x=" + x);  
  33.     }  
  34. }  


输出结果为:

Sub.x=0
Sub.x=30
20

对于后两个很容易理解,对于第一个 Sub.x=0

首先,

[java]  view plain  copy
  1. Base b = new Sub();直接找到子类的构造器,由于子类构造器没有显示的使用superthis,所以隐藏super(),调用父类无参构造器  
[java]  view plain  copy
  1. 构造器构造器先调用superthis,直到调用到Object类,  
[java]  view plain  copy
  1. </pre><pre name="code" class="java">然后父类开始实例化对象,执行 int x  = 10;  
[java]  view plain  copy
  1. </pre><pre name="code" class="java">然后父类执行构造器中第一句:  
[java]  view plain  copy
  1. <pre name="code" class="java">this.printMessage();  
[java]  view plain  copy
  1. </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


猜你喜欢

转载自blog.csdn.net/ifenggege/article/details/80570736