Java 9接口与类的区别

43

随着Java 9允许在接口中定义privateprivate static方法,那么在interfaceclass之间还剩下什么区别呢?此外,Java是否正在逐渐向多继承迈进?


31
我很惊讶这有那么多的赞... 其他方面仍有差异:protected 的支持,package-private 的支持,基本上是除了 privatestatic 之外的所有内容.. 接口无法扩展类,保留关键词 interfaceclass,两者存在的哲学/目的/原因... 可能还有其他差异。 - Dioxin
3
答案与 Java 8 中默认方法接口与抽象类的比较 的答案相同,只是现在接口可以有 private 方法,而这些方法显然不会影响其他类。 - Holger
5
@Aakash 学生: “有愚蠢的问题吗?” @教授:“当然没有!” 如果学生在刚得到答案后再次问同样的问题,那么这不是一个愚蠢的问题吗? 这个短语背后的思想是“不要害怕提问,这是你获得答案的方式”,不要滥用它来鼓励懒惰。 - Dioxin
1
@VinceEmigh,你的赞数比第二高的回答还要多:) 你应该把你的评论变成一个。 - Eugene
如果您了解Java类,那么接口和类之间的剩余差异是什么?如果我们按照字面意思来理解您的问题,那么这听起来像是在询问人们Java类具有哪些特性。 - the8472
显示剩余3条评论
5个回答

46
Java 9中的私有接口方法和其他私有方法一样:它们必须有一个实现(即使在抽象类中),并且不能被子类调用或重写。因此,它们实际上与继承没有真正的交互。而多重继承方面,至少有三种类型: - 类型继承表示一个类型可以是另一个类型,例如String是Object。Java允许从第一天起通过接口进行类型的多重继承。 - 行为继承表示一个类型可以继承另一个类型的行为。在Java 8之前,只有类能够实现方法,因此只有这种单一的继承方式。随着Java 8推出了默认方法,接口可以实现方法,从而让Java具有行为的多重继承方式。 - 状态继承意味着类型继承了另一个类型的内部状态(即字段)。截止目前(Java 9和未来Java版本中提出的所有内容),只有类可以拥有状态,因此在这种情况下只有单一继承。
可以看出,私有接口方法在这里没有添加任何内容。
关于您对接口和类比较的问题,主要有两个区别:多重继承和状态。接口支持前者,类可以拥有后者。由于状态在典型的OOP中是非常重要的,所以类仍然很有用。
如果接口能够强制实现具有特定的非公共字段或直接定义自己的字段,则该情况会改变,从而让接口能够与类竞争。

虽然这不太美观,我也不想在生产环境中看到它,但是状态是否可以通过内部类封装来模拟多重类继承呢?类似于这个:https://dev59.com/hXA75IYBdhLWcg3wMl8Z#3442218 - Terran
由于内部类以及引用它的字段将是公共的,因此这并不算继承私有状态。;) 公共状态没有问题,只需将与状态相关的方法提取到接口中即可。 - Nicolai Parlog

29

私有方法不会被子类继承,所以这个特性不会影响实现类。我认为接口中的私有方法允许我们在默认方法之间共享代码。

Java接口仍然不能拥有非静态成员。这是一个很大的区别,而且在我看来并不是多重继承。


20

Java 9接口仍然不能包含字段和构造函数。这使得类和接口之间有很大的区别,因此Java 9远未实现多继承。


2

Java 9版本中的接口可以拥有私有方法,但必须是静态私有方法。这个特性被引入是为了允许模块化方法。每个函数都应该只负责一个职责,而不是使用冗长的默认方法。与多重继承无关。

私有静态方法越多,您将能够编写更干净和可重复使用的代码。

无论是公共还是受保护的静态方法都不能被覆盖。


2
尽管这是一个老问题,但我也想发表一下我的看法 :)
  1. 抽象类:在抽象类中,我们可以声明实例变量,这些变量是子类所需的。

    接口:在接口中,每个变量都是public static和final的,我们不能声明实例变量。

  2. 抽象类:抽象类可以讨论对象的状态。

    接口:接口永远不能讨论对象的状态。

  3. 抽象类:在抽象类中,我们可以声明构造函数。

    接口:在接口中,我们不能声明构造函数,因为构造函数的目的是初始化实例变量。如果我们不能在接口中有实例变量,那么有什么必要在那里使用构造函数呢?

  4. 抽象类:在抽象类中,我们可以声明实例和静态块。

    接口:接口不能具有实例和静态块。

  5. 抽象类:抽象类无法引用lambda表达式。

    接口:具有单个抽象方法的接口可以引用lambda表达式。

  6. 抽象类:在抽象类中,我们可以重写OBJECT CLASS方法。

    接口:我们不能在接口中重写OBJECT CLASS方法。

我想说的是:

接口中的默认方法/静态方法概念只是为了节省实现类而不是提供有意义的有用实现。默认方法/静态方法是一种虚假实现,"如果您愿意,您可以使用它们,或者您可以覆盖它们(在默认方法的情况下,在实现类中)" 因此,每当在接口中添加新方法时,这样可以避免在实现类中实现新方法。 因此,接口永远无法等同于抽象类。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接