@Override注解详解

@Override注解详解

java 开发时经常会碰到@Override注解,从字面上来理解就是覆盖的意思

该注解的作用主要有两个:

  • 帮助自己检查是否正确的重写了父类中已有的方法

  • 告诉读代码的人,这是一个重写的方法

比如我们有如下基类

package com.test;

public class Fruit {
  public void show_name(int num){
    System.out.println("Fruit: "+num);
  }
  
  public static void main(String[] args) {
    // TODO code application logic here
    Fruit apple = new Apple(); //generate a kind of new fruit
    apple.show_name(2);
  }
}

之后我们编写一个Apple子类,继承这个基类。并且复写基类中的show_name()方法。

package com.test;

public class Apple extends Fruit{

  @Override
  public void show_name(int num){
    System.out.println("Apple:"+num);
  }
}

执行的结果,显而易见就是会打印出 Apple:2 字样。

其实,在我们手工重写父类的方法时,容易把方法的参数记错,如果此时不加@Override的话,编辑器就不会提示你:例如我们不加这个标签,悄悄的把参数改为float型。

public void show_name(float num){
    System.out.println("Apple");
}

这个时候,其实我们并没有按照我们的意图成功重写方法,于是一个隐藏的bug就这样诞生了,但如果加上@Override,
此时IDE就会提示重写失败。很容易地,我们会将重写方法错写为重载方法。

补充:

《Thinking in java》的作者Bruce在讨论这个问题的时候,提到了一个问题就是override私有的方法的例子:

现在我们向Fruit类中添加一个私有方法,而在Apple中尝试重写

@Override

private void grow(){

}

结果编译器会提示错误,这是一个非常低级的错误,但是有时候恰恰就不会被我们发现:那就是试着重写私有方法,但是当我们去掉Override标签的时候,编译器是不会报错的,而且可以执行。

其实Apple中的你所谓复写的grow只是一个针对于Apple本身的私有方法。完全是一个新的方法。

这就引出了一个问题,何为重写?

在面向对象中,只有接口和共有方法,继承方法才有重写,私有方法不可以重写,实际上:不是不可以重写而是,根本就不存在重写私有方法的概念!

这正是面向对象设计的初衷,私有方法本身就是为了封装在类内部,不希望别人来更改或者外部引用的,看到这里,忽然觉得,java设计的还真是不错,感觉到了思想和实现的统一。

posted @ 2021-08-12 17:35  草系编程苦手  阅读(6270)  评论(0编辑  收藏  举报