- Java教程
- Java - 主页
- Java - 概述
- Java - 环境设置
- Java - 基本语法
- Java - 变量类型
- Java - 基本数据类型
- Java - 基本运算符
- Java 控制语句
- Java - 循环控制
- Java - 决策
- Java - 如果-否则
- Java-开关
- Java - For 循环
- Java - For-Each 循环
- Java - While 循环
- Java - do-while 循环
- Java - 中断
- Java - 继续
- 面向对象编程
- Java - 对象和类
- Java - 方法
- Java - 构造函数
- Java - 访问修饰符
- Java-继承
- Java-多态性
- Java - 重写
- Java-抽象
- Java-封装
- Java - 接口
- Java - 包
- Java - 内部类
- Java 数据类型
- Java - 字符
- Java 文件处理
- Java - 文件和 I/O
- Java 错误与异常
- Java - 异常
- Java多线程
- Java-多线程
- Java同步
- Java-同步
- Java-线程间通信
- Java-线程死锁
- Java-线程控制
- Java网络
- Java-网络
- Java-URL 处理
- Java - 泛型
- Java集合
- Java - 集合
- Java列表接口
- Java - 列表接口
- Java队列接口
- Java - 队列接口
- Java地图接口
- Java - 地图接口
- Java - SortedMap 接口
- Java设置接口
- Java - 设置接口
- Java - SortedSet 接口
- Java数据结构
- Java - 数据结构
- Java-枚举
- Java 集合算法
- Java - 集合
- Java - 迭代器
- Java - 比较器
- Java杂项
- Java - 正则表达式
- Java-序列化
- Java - 发送电子邮件
- Java - Applet 基础知识
- Java - 文档
- Java 有用资源
- Java - 问题与解答
- Java - 快速指南
- Java - 有用的资源
- Java - 讨论
- Java - 示例
Java - 重写
在上一章中,我们讨论了超类和子类。如果一个类从其超类继承了一个方法,那么只要该方法未标记为final,就有机会重写该方法。
重写的好处是:能够定义特定于子类类型的Behave,这意味着子类可以根据其要求实现父类方法。
在面向对象术语中,覆盖意味着覆盖现有方法的功能。
例子
让我们看一个例子。
class Animal { public void move() { System.out.println("Animals can move"); } } class Dog extends Animal { public void move() { System.out.println("Dogs can walk and run"); } } public class TestDog { public static void main(String args[]) { Animal a = new Animal(); // Animal reference and object Animal b = new Dog(); // Animal reference but Dog object a.move(); // runs the method in Animal class b.move(); // runs the method in Dog class } }
输出
Animals can move Dogs can walk and run
在上面的示例中,您可以看到,即使b是 Animal 的一种类型,它也运行 Dog 类中的 move 方法。原因是:在编译时,对引用类型进行检查。然而,在运行时,JVM 会计算出对象类型并运行属于该特定对象的方法。
因此,在上面的例子中,由于 Animal 类有 move 方法,程序将正确编译。然后,在运行时,它运行特定于该对象的方法。
考虑以下示例 -
例子
class Animal { public void move() { System.out.println("Animals can move"); } } class Dog extends Animal { public void move() { System.out.println("Dogs can walk and run"); } public void bark() { System.out.println("Dogs can bark"); } } public class TestDog { public static void main(String args[]) { Animal a = new Animal(); // Animal reference and object Animal b = new Dog(); // Animal reference but Dog object a.move(); // runs the method in Animal class b.move(); // runs the method in Dog class b.bark(); } }
输出
TestDog.java:26: error: cannot find symbol b.bark(); ^ symbol: method bark() location: variable b of type Animal 1 error
该程序将引发编译时错误,因为 b 的引用类型 Animal 没有名为 bark 的方法。
方法重写规则
参数列表应该与重写方法的参数列表完全相同。
返回类型应该与超类中原始重写方法中声明的返回类型相同或其子类型。
访问级别不能比被重写方法的访问级别更严格。例如:如果超类方法声明为 public,则子类中的重写方法不能为 private 或 protected。
实例方法只有被子类继承时才可以被重写。
声明为final的方法不能被覆盖。
声明为静态的方法不能被重写,但可以重新声明。
如果一个方法不能被继承,那么它就不能被覆盖。
与实例的超类位于同一包中的子类可以重写任何未声明为 private 或 Final 的超类方法。
不同包中的子类只能重写声明为 public 或 protected 的非最终方法。
重写方法可以抛出任何未检查异常,无论被重写方法是否抛出异常。但是,重写方法不应抛出新的或比被重写方法声明的异常更广泛的已检查异常。重写方法可以抛出比被重写方法更窄或更少的异常。
构造函数不能被重写。
使用 super 关键字
当调用重写方法的超类版本时,使用super关键字。
例子
class Animal { public void move() { System.out.println("Animals can move"); } } class Dog extends Animal { public void move() { super.move(); // invokes the super class method System.out.println("Dogs can walk and run"); } } public class TestDog { public static void main(String args[]) { Animal b = new Dog(); // Animal reference but Dog object b.move(); // runs the method in Dog class } }
输出
Animals can move Dogs can walk and run