@Override注解表示当前的方法定义会覆盖父类中的方法。使用@Override注解,编译器会自动检查该方法是否真的覆盖了父类的方法,如果没有会报错。这可以避免因为继承关系的变化,子类不小心覆盖了父类的方法造成的错误。
@Override注解通常用在实现接口方法和继承类方法的时候。例如:
java
public interface MyInterface {
void method1();
}
public class MyClass implements MyInterface {
@Override
public void method1() {
// 实现方法
}
}
java
public class Parent {
public void method1() {
//...
}
}
public class Child extends Parent {
@Override
public void method1() {
// 覆盖父类方法
}
}
使用@Override的注意事项:
@Override注解不能用在静态方法上,因为静态方法不能被覆盖,只能被重载。
当方法签名改变时,子类的该方法就不能算是覆盖父类的方法。例如方法名称、参数列表或返回值类型不同,都会造成签名的改变。这时需要修改子类的方法,使其签名与父类方法一致,或者去掉@Override注解。
@Override注解只适用于方法,不能用于属性或构造函数的覆盖。
接口的默认方法可以使用@Override注解覆盖。
子类的访问修饰符需要与父类方法的访问修饰符具有兼容性,通常需要相同或更宽松。
使用@Override的好处:
提高代码的可读性,一眼就能看出是覆盖了父类的方法。
编译时检查,及早发现签名不一致的错误。
子类修改方法签名时(如增加参数),会提示必要修改。
确保子类真的覆盖了父类的方法,避免覆盖错误。
接口 default 方法也可覆盖。
@Override并不是必须的,如果不写也不会影响代码运行。但是使用@Override可以让编译器帮我们自动检查是否进行了正确的方法覆盖,所以Strongly recommended使用。
下面再介绍下Java中方法覆盖的规则:
子类方法访问权限必须大于等于父类方法。
子类方法返回类型必须是父类方法返回类型或为其子类型。
子类方法抛出的异常类型必须是父类抛出异常类型或为其子类型。
如果父类方法参数为final类型,则子类覆盖方法的参数也必须一样。
实例:
java
public class Parent {
protected Object method() throws Exception {...}
}
public class Child extend Parent {
@Override
public String method() throws RuntimeException { //正确覆盖
}
}
上面 Child 对 Parent 的 method() 进行了正确覆盖。
父类方法返回 Object,子类返回 String,满足第2条规则。父类抛 Exception,子类抛 RuntimeException,满足第3条规则。
如果子类这样写:
public class Child extend Parent {
private Object method() throws SQLException{ //错误覆盖
}
}
这时就违反了第1条规则和第3条规则。
总结一下,@Override注解就是用于表示当前方法定义会覆盖父类中的方法定义,它可以让编译器自动检查覆盖是否正确。
使用@Override注解的好处有:
提高可读性,一眼能看出是覆盖方法。
编译时检查,及早发现签名不一致错误。
修改方法签名时,编译器会提示必要修改。
避免覆盖父类错误的方法。
接口默认方法也可以覆盖。
所以,使用@Override注解是一个很好的编程习惯,可以让代码更加健壮,降低出错概率。
几个使用@Override注解的代码示例:
覆盖接口默认方法
java
public interface MyInterface {
default void method1() {
System.out.println("Interface");
}
}
public class MyClass implements MyInterface {
@Override
public void method1() {
System.out.println("Class");
}
}
覆盖抽象类方法
java
public abstract class AbstractClass {
public abstract void method1();
}
public class MyClass extends AbstractClass {
@Override
public void method1() {
System.out.println("Implemented method");
}
}
覆盖父类方法
java
public class Parent {
public void method1() {
System.out.println("Parent method");
}
}
public class Child extends Parent {
@Override
public void method1() {
System.out.println("Child method");
}
}
子类方法与父类同名,使用@Override标注区分
java
public class Parent {
public void method1() {
System.out.println("Parent method1");
}
public void method2() {
System.out.println("Parent method2");
}
}
public class Child extends Parent {
public void method1() {
System.out.println("Child method1");
}
@Override
public void method2() {
System.out.println("Child method2");
}
}
重载与覆盖方法使用@Override区分
java
public class Parent {
public void method1(int a) {}
}
public class Child extends Parent {
@Override
public void method1(int a) {}
public void method1(String s) {} //重载
}
使用@Override注解时的错误代码示例:
静态方法不能使用@Override
java
public class Parent {
public static void method1() {}
}
public class Child extends Parent {
@Override
public static void method1() {} // 错误,不能覆盖静态方法
}
方法签名不一致
java
public class Parent {
public void method1(int a) {}
}
public class Child extends Parent {
@Override
public void method1(String s) {} // 错误,参数类型不一致
}
子类方法访问权限不够
java
public class Parent {
public void method1() {}
}
public class Child extends Parent {
@Override
private void method1() {} // 错误,访问权限不一致
}
子类的返回值类型与父类不一致
java
public class Parent {
public String method1() {
return "";
}
}
public class Child extends Parent {
@Override
public int method1() { // 错误,返回值类型不一致
return 1;
}
}
子类抛出的异常与父类不一致
java
public class Parent {
public void method1() throws Exception {
}
}
public class Child extends Parent {
@Override
public void method1() throws SQLException { // 错误,异常类型不一致
}
}