子类继承了父类,在子类中声明了与父类具有相同的方法签名(指相同的方法名称与参数列表),并且具有相同的返回类型(或者子类的返回类型是父类的子类型)的实例方法,那么就说子类重写了父类中的同名方法(父类的方法必须在子类中可见)。重写是实现多态的前提,子类可以上溯造型为父类类型,这样,当通过父类的引用来调用重写的方法是,就可以表现出子类的行为。
方法重写的条件:
1.子类与父类的方法必须都是实例方法,如果父类是实例方法而子类是静态方法,或者相关,则编译器会报错。如果子类与父类都是静态方法,那么子类隐藏父类的方法,而不是重写父类的方法。即方法的重写不能发生在实例与静态方法之间,父类与子类的方法必须都是实例方法。
2.子类与父类的方法需要具有相同的方法名称,参数列表,并且子类的返回类型与父类相同或者是父类的子类型。如果方法名称相同而参数列表(返回类型可相同也可不同),那么只是方法重载。如果方法名称与参数列表相同而返回类型不同(并且子类方法的返回类型不是父类的子类型),那么编译器会报错。
import javax.swing.JComponent;
public class Super {
public JComponentdoSometing(){return null;}
public StringdoSomething2(){return null;}
}
import javax.swing.JButton;
public class Sub extends Super {
public JButtondoSomething(){return null;/*方法体内-----*/} //返回类型可以是父类方法的子类型,属于重写
public intdoSomething(){----------} //错误
public int doSomething(intx){ return x;}; //重载
public StringdoSomething2(){return null;}//返回类型与父类的返回类型相同,属于重写
//由于JButton是JComponent的子类,因此也满足重写的条件
}
3.子类方法的访问权限不能小于父类方法的访问权限(可以具有相同的访问权限)
class Super{
public void doSomething(){}
}
class Sub extends Super{
protected voiddoSomething(){----} //错误
}
访问权限由高到低为public,protected,包访问权限,private,如果子类方法的访问权限低于父类方法的访问权限,那么编译器会报错。
4.子类方法不能比父类方法抛出更多的已检测异常(也称编译时异常),即子类方法抛出的已检测异常必须是父类的子集(可以与父类抛出相同的异常)。
import java.io.FileNotFoundException;
public class Super {
public voiddoSometing()throws FileNotFoundException{}
}
import java.io.IOException;
public class Sub extends Super {
public voiddoSomething()throws IOException{} //错误
}
因为父类中抛出的FileNotFoundException类是子类抛出的IOException类的子类,这是不允许的。
5.父类的方法在子类中必须可见,即子类继承了父类中的方法(子类可以使用super来访问父类中被重写的方法)。子类只有继承了父类的方法才能重写父类中的方法,如果子类中声明了与父类完全相同的方法(方法名称,参数列表,返回类型均相同),但是父类中的该方法子类没有继承(不能通过super访问),比如父类中声明为private的方法,那么便不是重写。
public class Super {
private void doSometing(){}
}
public class Sub extends Super {
public voiddoSomething(){} //编译没有错误,但不是重写
}
因为父类声明为private的方法在子类中无法访问,尽管满足重写的其他条件,但也不是重写.
静态方法隐藏:当子类继承了父类,在子类中声明了与父类具有相同的名称,参数类表,并且具有相同的返回类型(或者子类的返回类型时父类的子类型)的静态方法时,那么子类便隐藏了父类中的同名方法(前提为该方法在子类中可见).
静态方法隐藏的条件:
1.子类与父类的方法必须都是静态方法
2.子类与父类的方法需要具有相同的方法名称,参数列表,并且子类的返回类型与父类相同或者是父类的子类型
3.子类方法的访问权限不能小于父类方法的访问权限(可以具有相同的访问权限).
4.子类方法不能比父类抛出更多的已检测异常,即子类方法抛出的已检测异常必须是父类的子集(可以与父类抛出相同的以检测异常,对于未检测异常,则不受此限制)
可以看出,除了方法重写是实例方法,方法隐藏式静态方法外,其余要求都是一样的.如果子类重写了父类的方法,则通过父类的引用调用的是子类的方法.如果子类隐藏了父类的方法,则通过父类的引用调用的仍然是父类的方法,这表明实例方法的调用时动态绑定的,是在运行时根据对象的真正的类型来决定调用哪个方法,而静态方法的调用时静态绑定的,是根据引用的类型来决定调用哪个方法.