大可制作:QQ群:31564239(asp|jsp|php|mysql)

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成员。