有時候重新定義方法時,並非完全不滿意父類別中的方法,只是希望在執行父類別中方法的前、後作點加工。例如,也許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
,子類別中重新定義時不可為private
或protected
。例如:
在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中並不會出現編譯錯誤。
static
方法屬於類別擁有,如果子類別中定義了相同簽署的static
成員,該成員屬於子類別所有,而非重新定義,static
方法也沒有多型,因為物件不會個別擁有static
成員。