java - Java 8 中的接口(interface)

标签 java inheritance java-8

<分区>

J. Bloch 在他为 Java 6 编写的 Effective Java 中提到了以下内容(第 17 项):

If you feel that you must allow inheritance from such a class, one reasonable approach is to ensure that the class never invokes any of its overridable methods and to document this fact. In other words, eliminate the class’s self-use of overridable methods entirely.

第 18 项:

If you use abstract classes to define types, you leave the programmer who wants to add functionality with no alternative but to use inheritance. The resulting classes are less powerful and more fragile than wrapper classes.

While interfaces are not permitted to contain method implementations, using interfaces to define types does not prevent you from providing implementation assistance to programmers.

现在在 Java 8 中,其默认方法的实现(使用接口(interface)中的其他方法)接口(interface)对于继承是危险的。

例如:

public inteface MyInterface{

   public void compute(Object o);

   public default void computeAll(List<Object> oo){
         for(Object o: oo)
            compute(o);       //self-use
   }
}

因此,根据 J. Bloch 的说法,当我们尝试实现接口(interface)时可能会引入一些问题,因为:

  1. 重写这样的方法(类似于 J.Bloch 提供的方法):

    public class MyInterfaceCounter implements MyInterface{
    
      private int count = 0;
    
      @Override
      public void compute(Object o) {
        count++;
      }
    
      @Override
      public void computeAll(List<Object> oo){
        count += oo.size();            //Damn!!
        MyInterface.super.computeAll(oo);
      }
    }
    
  2. 客户端访问接口(interface)的内部,即他们必须了解默认实现。

在 Java 8 中如何处理它? Effective Java apply 中的规则是否仍然适用?

此外,我们不能将默认方法声明为 final(就像我们可以为类做的那样,这将使自用对重写者来说不太危险)。

最佳答案

好的,从your previous question中获取答案看看我们可以在这里应用什么:

You could simply avoid self-use.

在这种情况下你不能。在实现该接口(interface)时,您唯一依赖的选择(如果您想要提供默认实现)是方法 compute。您必须使用它或根本不提供实现。

You could make one of the methods involved final, so it can't be overridden.

这在界面中也行不通。

You could make the class final, so it can't be extended.

这在界面中不起作用。

You could describe the class's self-use patterns in its Javadoc comment (meeting the requirement of letting other people know).

这是唯一的选择。要么记录它,要么不给出默认实现。 所以是的,它的基本思想仍然适用,但是您的选择有些有限。

关于java - Java 8 中的接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31111018/

相关文章:

Java Map<String,String[]> 如何对值求和

java - 如何在 Java8 流/过滤器中使用非最终变量?

java - Android 应用程序 - 根据按下次数从按钮输入整数

java - 如果我调用两次 bufferreader 会引用哪里

c++ - 多重继承来自多重继承

Python类继承构造函数失败: What am I doing wrong?

java - 使用 Apache fop 时条形码未显示在 pdf 上

java - Android Studio 拒绝运行 main()

c++ - 在 C++ 中创建继承结构时如何设置父成员

java - 为什么 distinct 通过 flatMap 工作,而不是通过 map 的 "sub-stream"工作?