【问题标题】:In Java 8 does Interface breaks the concept of encapsulation?在 Java 8 中,Interface 是否打破了封装的概念?
【发布时间】:2023-03-09 22:20:01
【问题描述】:

直到 Java1.7,我很高兴我使用接口来实现 OOP 的概念封装。意味着如果我想对最终用户隐藏实现,那么我将只与他们共享接口,他们可以使用该接口调用我的 API,例如 EJB。

以上在 Java 1.7 之前有效,现在在 Java 8 中,我可以在接口中编写方法的实现,也可以使用 defaultstatic 关键字,例如:

public interface Foo {

    public abstract int someUnimplementedMethod();

    default void printMsg() {
        System.out.println("Hello...!");
    }

    static void sayHello() {
        System.out.println("Hello...!");
    }

}

这在 Java 1.8 中完全有效。

现在我的问题是:

  • 在 Java 8 中,我们是否尝试通过 defaultstatic 方法引入称为 部分封装 的东西?

  • 我知道你们中的一些人会争辩说,如果你不想共享实现,那么最好在子接口中提供defaultstatic 实现,并使用抽象方法保留父接口,但现在不是当然,如果我用抽象方法编写了一个接口,新手可能只在接口中编写整个实现。所以它提出了一个问题,最好不要在接口中实现方法。

如果您不同意我的第二点,请提供解决方案。

顺便说一句,我读过Java documentation,其中指出:

默认方法使您能够向库的接口添加新功能,并确保与为这些接口的旧版本编写的代码的二进制兼容性。

【问题讨论】:

  • 你仍然不能在接口中有字段,所以你不能有状态,这也意味着封装真的与接口的变化无关。
  • @LouisWasserman 请在答案部分详细说明您的评论或提供一些有用的链接,您所说的“封装与界面的更改实际上无关”的意思,它会有所帮助。谢谢..
  • “Java1.7,很高兴我使用接口来实现 OOP 概念封装” ...很好奇,因为接口真的与封装或数据隐藏没有任何关系直接。
  • “在 Java 8 中,我们是否试图通过默认和静态方法引入称为部分封装的东西?” ...默认方法是达到目的的一种手段:一种方法在不破坏数十年的现有代码的情况下发展遗留的 Java 接口。默认方法确实在 Java 中引入了更多的多重继承,特别是实现(或行为)的多重继承。 Java 仍然禁止状态的多重继承。

标签: java oop interface java-8


【解决方案1】:

我会说这些是我们在 Java 8 之前所拥有的功能之上的附加功能

就像你说的,它是正确的 - 可以有 default 和静态(仅可用于接口,不能被覆盖。)

从 oracle 中,当你扩展一个包含默认方法的接口时,你可以执行以下操作

  1. 根本不提默认方法,让你的扩展接口继承默认方法。
  2. 重新声明默认方法,使其抽象化。
  3. 重新定义默认方法,将其覆盖。

所以我不知道该怎么称呼它(部分封装与否),它们是默认实现并且可以被覆盖。隐藏实际实现仍然是这里的一个功能。

java.utils 中的集合使用默认方法来支持 lambda 表达式。现在有一些可能会有所帮助的场景。

  1. 在很多应用程序中,我们需要一个基本实现类,然后我们扩展该类,即BaseImplClass implements IsomeInterface 因此,您可以选择在接口中定义这些默认实现,而不是 BaseImplClass如果需要,覆盖。

  2. 如果您有任何帮助程序或实用程序类,您可以在接口中使用静态方法...它们是公共的、最终的并且不能被覆盖

现在如果您想到可能出现的菱形问题(如果一个类实现了具有相同默认方法签名的多个接口,我们将遇到模棱两可的情况。答案是否定的,在这种情况下您将在编译时出错。并且你必须重写那个方法。

【讨论】:

  • “在很多应用程序中,我们需要一个基本的实现类......因此,您可以选择在接口中定义这些默认实现,而不是 BaseImplClass ” ...我想指出,接口的骨架、基础或抽象实现仍然是一种有用的设计。仅当可以仅使用对接口方法的调用来实现实现时,才存在将骨架实现替换为具有默认方法的接口的选项。如果需要状态,那么抽象类通常仍然是正确的调用。
【解决方案2】:

答案 1: 我相信默认方法提供了部分封装。因为每当我们将代码包装在一个类中(现在可以在接口内部)时,封装就在那里。它主要是一种当代的抽象方法,我们可以提供我们想要做的事情,而不是我们想要做的事情。

Answer2:这不是一个新问题,新手可能比这更危险。我认为我们可以设置检查样式以不允许此类方法。

【讨论】:

  • “我相信默认方法提供了部分封装。因为无论何时我们将代码封装在一个类中(现在可以在接口内部),封装就在那里。主要是它是一种当代的抽象方法,在这里我们可以提供我们想要做的事情,而不是我们想要做的事情。” ...我很确定我不知道这意味着什么。
猜你喜欢
  • 2010-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-20
  • 1970-01-01
  • 2015-12-27
  • 2019-02-05
相关资源
最近更新 更多