【面试干货】Java方法重写的规则
在Java中,方法重写(Overriding)是面向对象编程中的一个核心概念,它允许子类提供一个与父类相同名称、相同参数列表的方法,以实现或修改父类方法的行为。但是,方法重写并不是随意的,它必须遵循一定的规则。
1、Java方法重写的规则
-
方法名和参数列表必须完全一致
重写的方法必须与父类中被重写的方法具有完全相同的方法名和参数列表。参数列表包括参数的类型、顺序和个数。
-
返回值类型必须一致或为其子类型
重写方法的返回值类型必须与被重写方法的返回值类型相同,或者是其子类型。在Java 5及以后的版本中,如果父类方法返回类型是
Object
,则子类重写该方法时可以返回任何类型的对象。 -
构造方法不能被重写
构造方法(Constructor)用于创建类的对象,不能被重写。子类可以通过调用
super()
关键字来调用父类的构造方法。 -
final方法不能被重写
如果一个方法被声明为
final
,则它不能被任何子类重写。final
方法是一种固定不变的方法,子类不能改变其行为。 -
static方法不能被重写(但可以被隐藏)
static
方法是属于类的,而不是属于类的实例的。因此,static
方法不存在重写,子类中的同名static
方法只是隐藏了父类中的同名static
方法。这种情况通常被称为方法隐藏(Method Hiding)。 -
访问权限不能比父类更低
重写的方法的访问权限(
public
、protected
、default、private
)不能低于被重写方法的访问权限。例如,如果父类中的方法是public
的,那么子类中的重写方法也必须是public
的。 -
重写之后的方法不能抛出更宽泛的异常
如果父类方法声明了不抛出任何异常,或者抛出了某个特定的异常,那么子类重写该方法时,不能抛出更宽泛的异常。子类可以抛出与父类方法相同的异常,或者不抛出任何异常。
2、示例代码
示例代码包括了一个父类 Parent 和一个子类 Child。在这个示例中,子类 Child 重写了父类 Parent 中的方法 show 和 anotherMethod。
package com.example;
import java.io.IOException;
// 父类 Parent
class Parent {
// 父类方法 show
public void show() {
System.out.println("父类 show 方法"); // 输出 "父类 show 方法"
}
// 父类方法 anotherMethod,声明可能抛出 IOException
// 注意:这里并没有实际抛出 IOException,只是声明可能会抛出
public void anotherMethod() throws IOException {
System.out.println("父类 anotherMethod 方法(未抛出 IOException)"); // 输出 "父类 anotherMethod 方法(未抛出 IOException)"
}
}
// 子类 Child 继承自 Parent
class Child extends Parent {
// 重写父类的 show 方法
@Override
public void show() {
System.out.println("子类 show 方法"); // 输出 "子类 show 方法"
}
// 重写父类的 anotherMethod 方法,遵循相同的异常签名
// 注意:这里也没有实际抛出 IOException,只是保持与父类方法相同的声明
@Override
public void anotherMethod() throws IOException {
// 调用父类的 anotherMethod 方法
super.anotherMethod();
// 在这里可以添加子类特有的逻辑
System.out.println("子类 anotherMethod 方法"); // 输出 "子类 anotherMethod 方法"
}
// 提供一个 main 方法来测试这两个类
public static void main(String[] args) {
// 创建父类对象
Parent parent = new Parent();
// 创建子类对象
Child child = new Child();
// 调用父类的 show 方法
parent.show();
// 调用子类的 show 方法(注意,虽然调用的是子类对象的方法,但由于是重写,所以输出会是 "子类 show 方法")
child.show();
try {
// 调用父类的 anotherMethod 方法(由于未实际抛出 IOException,所以不会进入 catch 块)
parent.anotherMethod();
// 调用子类的 anotherMethod 方法(同样,由于未实际抛出 IOException,所以不会进入 catch 块)
child.anotherMethod();
} catch (IOException e) {
// 如果 anotherMethod 方法实际抛出了 IOException,这里会捕获并处理异常
// 但在这个示例中,我们不会到达这里
e.printStackTrace();
}
}
}
3、总结
1、方法重写是Java面向对象编程中的一个重要特性,它允许子类在继承父类的基础上,对父类的方法进行扩展或修改。
2、但是,方法重写必须遵循一定的规则,以确保程序的正确性和可维护性。在设计和实现子类时,我们应该仔细考虑是否需要重写父类的方法,并遵循上述规则进行重写。