一、什么是方法的重写(override 或 overwrite)?
子类继承父类之后,可以对父类中同名同参数列表的方法进行重写覆盖操作。
二、应用:重写以后,当创建子类的对象后,调用的父类同名同参数列表的方法其实是调用了子类重写的方法。
三、举例:
//举例一:
public class Circle {
public double findArea(){
return Math.PI * radius * radius;//求面积
}
}
public class Cylinder extends Circle {
@Override
public double findArea() {//求表面积
return Math.PI * getRadius() * getRadius()
* 2 + 2 * Math.PI * getRadius() * getLength();
}
}
//举例二:
public class Account {
public void withdraw (double amount){
if(balance >= amount){
balance -= amount;
return;
}
System.out.println("余额不足!");
}
}
public class CheckAccount extends Account {
@Override
public void withdraw(double amount) {
if(amount < getBalance()){//余额足够消费
//方式一
// setBalance(getBalance() - amount);
//方式二
super.withdraw(amount);
}else if(overdraft >= amount - getBalance()){//余额+透支足够消费
overdraft -= (amount - getBalance());
//方式一
// setBalance(0);
//方式二
super.withdraw(getBalance());
}else{
System.out.println("超过可透支限额!");
}
}
}
四、重写的规则:
1、方法的声明:
权限修饰符 返回值类型 方法名(形参列表) throws 异常的类型{
//方法体
}
约定俗成:子类中的叫重写的方法,父类中的叫被重写的方法。
①子类中重写的方法的方法名和形参列表与父类中被重写的方法名和形参列表相同。
②子类中重写的方法的权限修饰符不小于父类中被重写的权限修饰符。
>特殊情况:子类不能重写父类中权限是private的方法。
③返回值类型
>如果父类被重写的方法的返回值类型是void,那么子类重写的方法的返回值类型必须是void
>如果父类被重写的方法的返回值类型是A类,那么子类重写的方法的返回值类型是A类或者A类的子类。
>如果父类被重写的方法的返回值类型是基本数据类型(例如:double),那么子类重写的方法的返回值类型必须是相同的基本数据类型(必须是double)。
④throws 异常的类型
>子类重写的方法抛出的异常不大于父类被重写的方法抛出的异常。
⑤子类和父类中同名同形参列表的方法要么都声明为非static的(考虑重写),要么都声明为static的(不是重写)。
五、经典面试题
区分方法的重写和重载?
1、二者的概念
①重载:“两同一不同”:同一个类、相同方法名。参数列表不同(包括参数列表数据类型不同,参数列表数量不同)
②重写:子类继承父类后,对于父类中的方法可以进行重写,要求方法名、参数列表都相同。
2、重写和重载的规则
3、重载:不表现为多态性
重写:表现为多态性
重载,是指允许存在多个同名方法,而这些方法的参数不同。编译器根据方法不同的参数表,对同名方法的名称做修饰。对于编译器而言,这些同名方法就成了不同的方法。它们的调用地址在编译期就绑定了。Java的重载是可以包括父类和子类的,即子类可以重载父类的同名不同参数的方法。
所以:对于重载而言,在方法调用之前,编译器就已经确定了所要调用的方法,这称为“早绑定”或“静态绑定”;
而对于多态,只有等到方法调用的那一刻,解释运行器才会确定所要调用的具体方法,这称为“晚绑定”或“动态绑定”。引用一句Bruce Eckel的话:“不要犯傻,如果它不是晚绑定,它就不是多态。”