共计 1718 个字符,预计需要花费 5 分钟才能阅读完成。
重写(Override)
重写是子类对父类的容许拜访的办法的实现过程进行从新编写, 返回值和形参都不能扭转。即外壳不变,外围重写!
重写的益处在于子类能够依据须要,定义特定于本人的行为。也就是说子类可能依据须要实现父类的办法。
重写办法不能抛出新的查看异样或者比被重写办法申明更加宽泛的异样。例如:父类的一个办法申明了一个查看异样 IOException,然而在重写这个办法的时候不能抛出 Exception 异样,因为 Exception 是 IOException 的父类,抛出 IOException 异样或者 IOException 的子类异样。
在面向对象准则里,重写意味着能够重写任何现有办法。实例如下:
TestDog.java 文件代码:
class Animal{
public void move(){
System.out.println("动物能够挪动");
}
}
class Dog extends Animal{
public void move(){
System.out.println("狗能够跑和走");
}
}
public class TestDog{
public static void main(String args[]){
Animal a = new Animal(); // Animal 对象
Animal b = new Dog(); // Dog 对象
a.move();// 执行 Animal 类的办法
b.move();// 执行 Dog 类的办法
}
}
以上实例编译运行后果如下:
动物能够挪动
狗能够跑和走
在下面的例子中能够看到,只管 b 属于 Animal 类型,然而它运行的是 Dog 类的 move 办法。
这是因为在编译阶段,只是查看参数的援用类型。
然而在运行时,Java 虚拟机 (JVM) 指定对象的类型并且运行该对象的办法。
因而在下面的例子中,之所以能编译胜利,是因为 Animal 类中存在 move 办法,然而运行时,运行的是特定对象的办法。
思考以下例子:
TestDog.java 文件代码:
class Animal{
public void move(){
System.out.println("动物能够挪动");
}
}
class Dog extends Animal{
public void move(){
System.out.println("狗能够跑和走");
}
public void bark(){
System.out.println("狗能够吠叫");
}
}
public class TestDog{
public static void main(String args[]){
Animal a = new Animal(); // Animal 对象
Animal b = new Dog(); // Dog 对象
a.move();// 执行 Animal 类的办法
b.move();// 执行 Dog 类的办法
b.bark();
}
}
以上实例编译运行后果如下:
TestDog.java:30: cannot find symbol
symbol : method bark()
location: class Animal
b.bark();
^
该程序将抛出一个编译谬误,因为 b 的援用类型 Animal 没有 bark 办法。
办法的重写规定
参数列表与被重写办法的参数列表必须完全相同。
返回类型与被重写办法的返回类型能够不雷同,然而必须是父类返回值的派生类(java5 及更早版本返回类型要一样,java7 及更高版本能够不同)。
拜访权限不能比父类中被重写的办法的拜访权限更低。例如:如果父类的一个办法被申明为 public,那么在子类中重写该办法就不能申明为 protected。
父类的成员办法只能被它的子类重写。
申明为 final 的办法不能被重写。
申明为 static 的办法不能被重写,然而可能被再次申明。
子类和父类在同一个包中,那么子类能够重写父类所有办法,除了申明为 private 和 final 的办法。
子类和父类不在同一个包中,那么子类只可能重写父类的申明为 public 和 protected 的非 final 办法。
重写的办法可能抛出任何非强制异样,无论被重写的办法是否抛出异样。然而,重写的办法不能抛出新的强制性异样,或者比被重写办法申明的更宽泛的强制性异样,反之则能够。
构造方法不能被重写。
如果不能继承一个类,则不能重写该类的办法。