Java實現多態的機制是後期綁定。
但Java也有些地方可以用前期綁定,比如:final,static,private(隱式final)和構造方法(隱式static)是前期綁定。
另外,Java只有普通方法的調用可以是多態的,如果直接訪問某個域,這個訪問將在編譯期進行解析。
舉例
//子類
public class Son extends Battle {
public int a = 2;
public int getA(){
return a;
}
}
//父類
public class Battle {
public int a = 1;
public int getA(){
return a;
}
public static void main(String[] args) throws Exception {
Battle b = new Son();
System.out.println(b.a);
System.out.println(b.getA());
}
}
輸出
構造器調用順序
先看如下代碼
class Meal {
Meal() { System.out.println("Meal()"); }
}
class Bread {
Bread() { System.out.println("Bread()"); }
}
class Cheese {
Cheese() { System.out.println("Cheese()"); }
}
class Lettuce {
Lettuce() { System.out.println("Lettuce()"); }
}
class Lunch extends Meal {
Lunch() { System.out.println("Lunch()"); }
}
class PortableLunch extends Lunch {
PortableLunch() { System.out.println("PortableLunch()"); }
}
public class Test extends PortableLunch {
private Bread b = new Bread();
private Cheese c = new Cheese();
private Lettuce l = new Lettuce();
public Test() { System.out.println("Test()"); }
public static void main(String[] args) {
new Test();
}
}
輸出
執行步驟是:
1、調用父類構造器。這個步驟會不斷遞歸下去,直到構造這種層次結構的根,然後是下一層的子類,直到最底層的子類。
1、按聲明順序調用成員的初始化方法。
3、調用子類構造器的主體。
同時調用層次中某一類的構造方法時,會先初始化成員變量。
按如下順序初始化類中的東西:
1、靜態屬性初始化
2、靜態方法塊初始化
3、普通屬性初始化
4、普通方法塊初始化
5、構造函數初始化
構造器內部的多態
先看代碼
class Glyph{
void draw(){
System.out.println("Glyph draw()");
}
Glyph(){
System.out.println("Glyph() before draw()");
draw();
System.out.println("Glyph() after fraw()");
}
}
class RoundGlyph extends Glyph{
private int radius = 1;
RoundGlyph(int r){
radius = r;
System.out.println("RoundGlyph.RoundGlyph(), radius = " + radius);
}
void draw(){
System.out.println("RoundGlyph.draw(), radius = " + radius);
}
}
public class Test {
public static void main(String[] args) {
new RoundGlyph(5);
}
}
輸出
分析一下代碼運行過程:
- 在其他任何事物發生之前,將分配給對象的存儲空間初始化爲二進制的零。
- 如上文一般,虛擬機在查看類的類型信息的時候,如果發現有父類,則繼續去加載父類的類文件,如果沒有父類了,則開始初始化類,再然後執行構造器。
- 這時在執行Glyph的構造器時發現它調用了子類重寫的draw方法,在這是一個多態。由於子類還沒有初始化,這時radius是剛開始分配存儲空間時初始化的0,因此打印出 RoundGlyph.draw(), radius = 0。
- 按照聲明的順序調用成員的初始化方法。
- 調用子類的構造器。