重写(Overriding)算是 Java 中一个非常重要的概念,重写带来了一种非常重要的能力,可以让子类重新实现从超类那继承过来的方法。子类可继承父类中的方法,而不需要重新编写相同的方法。但有时子类并不想原封不动地继承父类的方法,而是想作一定的修改,这就需要采用方法的重写。方法重写又称方法覆盖。
Java重写的方法和被重写的方法,不仅方法名相同,参数也相同,只不过,方法体有所不同。Java重写是需要遵循一些规则的,下面我们一一概述。
因为重写是在子类重新实现从父类继承过来的方法时发生的,所以只能重写继承过来的方法,这很好理解。这就意味着,只能重写那些被 public、protected 或者 default 修饰的方法,private 修饰的方法无法被重写。
一个方法是 final 的就意味着它无法被子类继承到,所以就没办法重写。
public class Animal {
final void move() { }
}
由于父类 Animal 中的 move()
是 final 的,所以子类在尝试重写该方法的时候就出现编译错误了!
public class Animal {
void eat(String food) { }
}
Dog 类中的 eat()
方法保持了父类方法 eat()
的同一个调调,都有一个参数——String 类型的 food。
父类没有返回类型:
public class Animal {
void eat(String food) { }
}
子类尝试返回 String:
public class Dog extends Animal {
public String eat(String food) {
return null;
}
}
可以这样来理解:
举例来说,如果父类中的方法抛出的是 IOException,那么子类中重写的方法不能抛出 Exception,可以是 IOException 的子类或者不抛出任何异常。这条规则只适用于可检查的异常。
可检查(checked)异常必须在源代码中显式地进行捕获处理,不检查(unchecked)异常就是所谓的运行时异常,比如说 NullPointerException、ArrayIndexOutOfBoundsException 之类的,不会在编译器强制要求。
子类继承父类的方法而不是重新实现是很常见的一种做法,在这种情况下,可以按照下面的形式调用父类的方法:
super.overriddenMethodName();
因为构造方法很特殊,而且子类的构造方法不能和父类的构造方法同名(类名不同),所以构造方法和重写之间没有任何关系。
先来看这样一个接口类:
public interface Animal {
void move();
}
接口中的方法默认都是抽象方法,通过反编译是可以看得到的:
public interface Animal
{
public abstract void move();
}
如果一个抽象类实现了 Animal 接口,move()
方法不是必须被重写的;
但如果一个类继承了抽象类 AbstractDog,那么 Animal 接口中的 move()
方法和抽象类 AbstractDog 中的抽象方法 bark()
都必须被重写:
synchronized 关键字用于在多线程环境中获取和释放监听对象,因此它对重写规则没有任何影响,这就意味着 synchronized 方法可以去重写一个非同步方法;
如果你想让浮点运算更加精确,而且不会因为硬件平台的不同导致执行的结果不一致的话,可以在方法上添加 strictfp 关键字。因此 strictfp 关键和重写规则无关。
以上就是Java重写的10条规则,我们只要在使用Java重写时谨记这些规则,就能避免很多容易出现的错误。在动力节点在线的Java SE视频课程中,有很多Java重写的实例,我们可以根据这些规则去重写代码,看看答案是否准确。
提枪策马乘胜追击04-21 20:01
代码小兵87207-15 12:10
杨晶珍05-11 14:54
杨晶珍05-12 17:30