1. 程式人生 > >Java 多型 後連結(late binding)與前連結(early binding) 向上轉型(upcast)

Java 多型 後連結(late binding)與前連結(early binding) 向上轉型(upcast)

使用過面向物件程式設計(OPP)的都知道,多型是OPP的一個主要特性之一。Java做為一種OPP語言,其也有多型特性。
那麼什麼是多型呢?

多型

指允許不同類的物件對同一訊息做出響應。即同一訊息可以根據傳送物件的不同而採用多種不同的行為方式。(傳送訊息就是函式呼叫)
先舉個例子,我們定義Shape類,Square和Circle繼承Shape類,並重載其draw方法。

public class Shape {
    public void draw() {
        System.out.println("draw in Shape!");
    }
}

class Square
extends Shape {
public void draw() { System.out.println("draw in Square!"); } } class Circle extends Shape { public void draw() { System.out.println("drwa in Circle!"); } }

測試程式碼如下,

    public static void main(String[] args) {
        Shape square = new Square();
        square.draw();
        Shape circle = new
Circle(); circle.draw(); }

測試結果為,

draw in Square!
drwa in Circle!

以上程式碼就涉及到多型現象。當我們呼叫draw方法時,Java會根據執行時物件的型別來判斷呼叫誰的方法。比如square在執行時是Square型別,就會呼叫其draw方法;circle也類似。
或許你會疑問,square的型別命名是Shape,為什麼能賦值為Square型別的呢。這就是向上轉型了。

向上轉型(upcast)

繼承最重要的不是給子類提供了方法,而是父類與子類的關係。該關係可以概括為子類是父類的一種(The new class is a type of the existing class)。
由於繼承意味著,父類的方法,在子類中也存在,所以向父類傳送的訊息(父類的方法呼叫),也可以傳送給子類。
這樣我們可以理解,Shape square = new Square();該語句為什麼可以通過編譯。
另外,向上轉型是安全的,這是由於,向上轉型是由特定的類轉為一般的類。也就是,子類是父類的超級(superset),子類包含所有父類的方法。

後連結(late binding)

上面提到Java會根據執行時物件的型別來判斷呼叫的方法,這就是後連結。與連結接相對的是,前連結。
將方法與方法的物件聯絡起來叫連結。在程式執行前完成連結的(由編譯器或連結器完成),叫前連結,C語言就是一個例子。
然而,Java中,由於多型,在編譯的時候,編譯器僅僅知道一個引用,無法知道呼叫哪個方法。後連結解決了該問題,在執行時根據物件的型別來連結方法。後連結也稱為動態連結(dynamic binding)、執行時連結(run-time binding)。
Java中,所有的方法都是後連結,除非,該方法宣告為final方法。很容易理解,因為final方法無法被重寫,所以編譯器可以知道該方法屬於哪個型別。