Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/398.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java @必须覆盖注释吗?_Java_Interface_Annotations_Abstract Class_Overriding - Fatal编程技术网

Java @必须覆盖注释吗?

Java @必须覆盖注释吗?,java,interface,annotations,abstract-class,overriding,Java,Interface,Annotations,Abstract Class,Overriding,在.NET中,可以为特定超类中的方法指定“mustoverride”属性,以确保子类重写该特定方法。 我想知道是否有人有一个定制的java注释可以达到同样的效果。本质上,我想要的是推动子类重写超类中的方法,该超类本身具有一些必须运行的逻辑。我不想使用抽象方法或接口,因为我想在超级方法中运行一些常见的功能,但或多或少会产生一个编译器警告/错误,指示派生类应该重写给定的方法。忽略抽象方法,Java中没有这样的功能。也许可以创建一个编译时注释来强制这种行为(我不相信是这样),但仅此而已 真正的关键是“

在.NET中,可以为特定超类中的方法指定“mustoverride”属性,以确保子类重写该特定方法。
我想知道是否有人有一个定制的java注释可以达到同样的效果。本质上,我想要的是推动子类重写超类中的方法,该超类本身具有一些必须运行的逻辑。我不想使用抽象方法或接口,因为我想在超级方法中运行一些常见的功能,但或多或少会产生一个编译器警告/错误,指示派生类应该重写给定的方法。

忽略抽象方法,Java中没有这样的功能。也许可以创建一个编译时注释来强制这种行为(我不相信是这样),但仅此而已

真正的关键是“重写一个超类中的方法,该超类本身有一些必须运行的逻辑”。如果重写方法,除非显式调用它,否则不会调用超类的方法

在这种情况下,我倾向于这样做:

abstract public class Worker implements Runnable {
  @Override
  public final void run() {
    beforeWork();
    doWork();
    afterWork();
  }

  protected void beforeWork() { }
  protected void afterWork() { }
  abstract protected void doWork();
}

在接口的方法上强制特定的逻辑结构。例如,您可以使用它来计算调用次数,而不必担心用户是否调用了
super.run()
,等等。

。。。如果声明一个基类
抽象
不是一个选项,那么您总是可以抛出一个UnsupportedOperationException

class BaseClass {
    void mustOverride() {
        throw new UnsupportedOperationException("Must implement");
    }
}

但这当然不是编译时检查…

我不确定您在.NET中考虑的是哪个属性

在VB中,您可以将
MustOverride
修饰符应用于方法,但这与在Java中使方法抽象相当。您不需要属性/注释,因为概念已内置到语言中。它不仅仅是应用元数据,还有一个关键的区别,即抽象方法本身不包含任何实现


如果您确实认为有这样一个属性,请您说出您指的是哪一个?

我不太明白为什么您不想使用抽象修饰符——这是为了强制子类实现,只需要用于某些方法,而不是所有方法。或者你在想C++风格的“纯抽象”类? 但是许多Java开发人员不知道的另一件事是,重写非抽象方法并将其声明为抽象方法也是可能的;比如:

public abstract String toString(); // force re-definition

因此,即使
java.lang.Object
已经定义了一个实现,您也可以强制子类重新定义它。

如果您需要一些默认行为,但由于某种原因,它不应该被专门化使用,与非抽象适配器类中的逻辑实现类似,只是为了简化原型设计,但不应在生产中使用,例如,您可以封装该逻辑并记录正在使用该逻辑的警告,而无需实际运行该逻辑

基类构造函数可以检查保存逻辑的变量是否指向默认值。(用非常抽象的术语写作,因为我认为它适用于任何语言)

它将类似于以下(未编译、未测试和不完整)Java(最多7个)示例:

根据需求的不同,有些事情可能会有所不同,而且显然更简单,特别是对于使用lambda表达式的语言,但基本思想是相同的


如果没有内置的东西,总会有一些方法来模拟它,在这个例子中,你会在日志文件中得到一个运行时警告,带有一个自制的类似于模式的解决方案,只有你的需要才应该指出它是否足够或是一个更核心的字节码操作,ide插件开发或任何需要的向导。

Android在Google I/O 2015中发布了一个新的注释: @超级呼叫

详情如下:
我一直在考虑这个问题

虽然我不知道有什么方法可以要求它出现编译错误,但是如果您忘记重写,您可以尝试编写一个自定义PMD规则来发出一个红色标志

已经有很多PMD规则,它们可以提醒您在选择覆盖equals时实现HhashCode。也许可以这样做

我以前从未这样做过,所以我不是编写教程的人,但在本例中,一个很好的起点是这个链接,如果您决定在导入包中使用通配符,他基本上会创建一个小警告。以此为起点,探索PMD如何分析您的源代码、访问层次结构的每个成员,以及确定您忘记在何处实现特定方法

注释也是一种可能性,但是您必须找到自己的方法来通过类路径实现导航。我相信PMD已经处理好了。此外,PMD与IDE有一些非常好的集成。

如果在Java中重写一个方法,将不再调用super类中的方法,除非使用显式的“super”。所以,我认为你的想法(强制执行一个普通的超类方法)是行不通的,即使这样一个属性会存在。这应该是公认的答案。很多时候,人们可能希望在super方法中使用基本逻辑,但要提醒未来的开发人员,如果不扩展此逻辑并调用super(),孩子就不能期望按照业务需要进行正常的行为。举个例子,大多数情况下我们都按原样使用基类。基类有一个返回深度副本的复制函数。调用ChildClass.copy()应返回ChildClass的新实例,而不是基类。我希望在编译时强制执行覆盖,以避免在生产中出现不复制一两个字段的细微错误,并返回0.+1作为有用信息,但不回答问题。我们需要一个注释,警告子类“必须重写此方法”
public interface SomeLogic {
 void execute();
}

public class BaseClass {

  //...private stuff and the logging framework of your preference...

  private static final SomeLogic MUST_OVERRIDE = new SomeLogic() {
    public void execute() {
      //do some default naive stuff
    }
  };

  protected SomeLogic getLogic() { return MUST_OVERRIDE; }

  //the method that probably would be marked as MustOverride if the option existed in the language, maybe with another name as this exists in VB but with the same objective as the abstract keyword in Java
  public void executeLogic() {
    getLogic().execute();
  }

  public BaseClass() {
    if (getLogic() == MUST_OVERRIDE) {
      log.warn("Using default logic for the important SomeLogic.execute method, but it is not intended for production. Please override the getLogic to return a proper implementation ASAP");
    }
  }

}

public GoodSpecialization extends BaseClass {

  public SomeLogic getLogic() {
    //returns a proper implementation to do whatever was specified for the execute method
  }

  //do some other specialized stuff...
}

public BadSpecialization extends BaseClass {

  //do lots of specialized stuff but doesn't override getLogic...
}