重新定義的細節


有時候重新定義方法時,並非完全不滿意父類別中的方法,只是希望在執行父類別中方法的前、後作點加工。例如,也許Role類別中原本就定義了toString()方法:

package cc.openhome;

public abstract class Role {
    ...略
    public String toString() {
        return String.format("(%s, %d, %d)", this.name, 
                this.level, this.blood);
    }
}

如果在SwordsMan子類別中重新定義toString()的內容時,可以執行Role中的toString()方法取得字串結果,再串接"劍士"字樣,不就是你想要的描述了嗎?在Java中,如果想取得父類別中的方法定義,可以於呼叫方法前,加上super鍵字。例如:

package cc.openhome;

public class SwordsMan extends Role {
    ...略
    @Override
    public String toString() {
        return "劍士 " + super.toString();
    }
}

類似地,Magician在重新定義toString()時,也可以如法泡製:

package cc.openhome;

public class Magician extends Role {
    ...略
    @Override
    public String toString() {
        return "魔法師 " + super.toString();
    }
}

可以使用super關鍵字呼叫的父類別方法,不能定義為private(因為這就限定只能類別內使用)。

重新定義方法要注意,對於父類別中的方法權限,只能擴大但不能縮小。若原來成員public,子類別中重新定義時不可為privateprotected。例如:

重新定義時不能縮小方法權限


在JDK5之前,重新定義方法時除了可以定義權限較大的關鍵字外,其它部份必須與父類別中方法簽署完全一致。例如原先設計了一個Bird類別:

public class Bird {
    protected String name;
    public Bird(String name) {
        this.name = name;
    }
    public Bird copy() {
        return new Bird(name);
    }
}

原先copy()傳回了Bird型態,如果Chicken繼承Bird,打算讓copy()方法傳回Chicken,那麼在JDK5之前會發生編譯錯誤:

JDK5之前重新定義方法時,返回型態也必須一致


在JDK5之後,重新定義方法時,如果返回型態是父類別中方法返回型態的子類別,也是可以通過編譯的,上圖的例子,在JDK5中並不會出現編譯錯誤。

static方法屬於類別擁有,如果子類別中定義了相同簽署的static成員,該成員屬於子類別所有,而非重新定義,static方法也沒有多型,因為物件不會個別擁有static成員。