java 多態

class B extends A 

繼承過後通常會定義一些父類沒有的成員或者方法。

A a = new B(); 

這樣是可以的,上傳。

a是一個父類對象的實例,因而不能訪問子類定義的新成員或方法。

 ========================================================== 

假如這樣定義:

class A{ 

int i; 

void f(){} 

class B extends A{ 

int j; 

void f(){}//

重寫

 

void g(){} 

然後:

B b = new B(); 

b就是子類對象的實例,不僅能夠訪問自己的屬性和方法,也能夠訪問父類的屬性和方法。

諸如b.i,b.j,b.f(),b.g()都是合法的。此時 b.f()是訪問的B中的f()

 A a = new B(); 

a雖然是用的B的構造函數,但經過upcast,成爲父類對象的實例,不能訪問子類的屬性和方法。a.i,a.f()是合法的,而a.j,a.g()非法。此時訪問a.f()是訪問B中的f() 

========================================================== 

A a = new B(); 

這條語句,實際上有三個過程:

 (1) A a; 

將a聲明爲父類對象,只是一個引用,未分配空間

 (2) B temp = new B(); 

通過B類的構造函數建立了一個B類對象的實例,也就是初始化

(3) a = (A)temp; 

將子類對象temp轉換未父類對象並賦給a,這就是上傳(upcast),是安全的。

 

經過以上3個過程,a就徹底成爲了一個A類的實例。

 

子類往往比父類有更多的屬性和方法,上傳只是捨棄,是安全的;而下傳(downcast)有時會增加,通常是不安全的。

 =========================================================== 

a.f()對應的應該是B類的方法f()

 調用構造函數建立實例過後,對應方法的入口已經確定了。

 如此以來,a雖被上傳爲A類,但其中重寫的方法f()仍然是B的方法f()。也就是說,每個對象知道自己應該調用哪個方法。

 

A a1 = new B(); 

A a2 = new C(); 

a1,a2兩個雖然都是A類對象,但各自的f()不同。這正是1樓說的多態性的體現。

 

這類問題在《Java編程思想》上都講的很清楚


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章