轉發一道java基礎題(多型)
阿新 • • 發佈:2018-11-11
這是在網上只看到的一道java關於多型繼承的問題,看著很簡單,結構出乎意料,也是研究了一天終於搞明白了一點
問題來自:http://blog.itpub.net/28562677/viewspace-1200194/
- public class DispatchTest {
- public static void
- 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
首先,
[java] view plain copy- 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