From Gossip@caterpillar

Java Gossip: 重新定義(Override)方法

類別是物件的定義書,如果原來的定義並不符合您的需求,您可以在擴充類別的同時重新定義,舉個例子來說,看看下面這個類別:
public class SimpleArray {
    protected int[] array;
 
    public SimpleArray(int i) {
        array = new int[i];
    }
 
    public void setElement(int i, int data) {
        array[i] = data;
    }

    ....
}

這個類別設計一個簡單的陣列輔助類別,不過您覺得它的setElement()方法不夠安全,您想要增加一些陣列的邊界檢查動作,於是擴充該類別, 並重新定義setElement()方法:
public class SafeArray extends SimpleArray {
    public SafeArray(int i) {
        super(i);
    }
 
    public void setElement(int i, int data) {
        if(i < array.length)
            super.setElement(i, data);
    }
 
    ....
}

這麼以來,以SafeArray類別的定義所產生的物件,就可以使用新的定義方法。

當同一個成員方法在衍生類別中被重新定義,使用此衍生類別所生成的物件來呼叫該方法時,所執行的會是衍生類別中所定義的方法,而基底類別中的同名方法並不受影響。

在上面您看到super()與super, 如果您在衍生類別中想要呼叫基底類別的建構方法,可以使用super()方法,另外若您要在衍生類別中呼叫基底類別方法,則可以如使用 super.methodName(),就如上面所示範的,但使用super()或super呼叫父類別中方法的條件是父類別中的該方法不能是 "private"。

重新定義方法時要注意的是,您可以增大父類別中的方法權限,但不可以縮小父類別的方法權限,例如在擴充SimpleArray時,您不可以這麼作:
public class SafeArray extends SimpleArray {
 ....
    private void setElement(int i, int data) {
        ....
    }
}

嘗試將setElement()方法從"public"權限縮小至"private"權限是不行的,編譯器會回報以下的錯誤訊息:
Test.java:18: setElement(int,int) in SafeArray cannot override setElement(int,in t) in SimpleArray; attempting to assign weaker accessprivileges; was public
private void setElement(int i, int data) {
^
1 error

J2SE 5.0 之後,在重新定義方法時,您可以重新定義返回值,例如您原先設計了一個Point2D類別:
public class Point2D {
    protected int x;
    protected int y;
 
    public Point2D(int x, int y) {
        this.x = x;
        this.y = y;
    }
 
    public Point2D getCopyOfMe() {
        return new Point2D(x, y);
    }
}
....
 
現在您擴充它,定義了一個Point3D類別:
public class Point3D extends Point2D {
    protected int z;
 
    public Point3D(int x, int y, int z) {
        super(x, y);
        this.z = z;
    }
 
    public Point3D getCopyOfMe() {
        return new Point3D(x, y, z);
    }
}
 ....

在J2SE 5.0之前,您會很苦惱於不能重新定義返回值,因此您勢必要重新寫一個方法名稱來傳回Point3D的返回值,但是在J2SE 5.0之後,重新定義返回值是可行的了,但使用時還是有限制條件,也就是重新定義的返回值型態必須是父類別中同一方法返回型態的子類別,或者是實作介面的類別,例如以下是可行的:
public interface ISome {
    ....
}

public class SomeImpl implements ISome {
    ....
}

public class Other {
    public ISome doSomething() {}
}

public class SubOther extends Other {
    public SomeImpl doSomething() {}
}

注意!您無法重新定義static方法,一個方法要被重新定義,它必須是非static的,如果您在子類別中定義一個有同樣簽署(signature)的static成員,那不是重新定義,那是定義一個屬於該子類別的static成員。