17

我想知道为什么 Java 的设计没有friendC++ 中可用的指令,以允许更好地控制哪些方法和实例变量可从定义类的包外部获得。

我没有看到任何实际原因或任何具体缺点,这似乎只是一个设计问题,但如果添加到语言中不会造成任何问题。

4

8 回答 8

10

总的来说,我认为这是因为它增加了认知复杂性,而且它创造了改进的案例数量很少。

我想说,此刻生产中的大量java行可以证明friend关键字并不是真正的大损失:)。

有关更具体的原因,请参阅@dwb 的回答。

于 2011-01-10T14:09:32.010 回答
10

以下是我脑海中浮现的几个原因:

  • 朋友不是必需的。这很方便,但不是必需的
  • 朋友支持不好的设计。如果一个班级需要朋友访问另一个班级,那你就错了。(见上文,方便,不需要)。
  • 朋友打破封装。基本上,我所有的隐私都属于我,还有那边的那个人(我的朋友)。
于 2011-01-10T14:12:56.920 回答
7

只有非常天真和缺乏经验的程序员才会反对朋友。当然,它可能会被滥用,但公共数据也可以,但提供了这种功能。

与流行观点相反,这里有很多情况,特别是对于基础设施功能,朋友访问导致更好的设计,而不是更差的设计。当一个方法被强制公开而实际上不应该公开时,通常会违反封装,但我们别无选择,因为 Java 不支持朋友。

于 2013-05-27T06:54:40.740 回答
4

除了前面提到的包可见性之外,Java 还提供了内部类和匿名类,它们不仅默认是朋友,而且自动具有对包含类的引用。由于创建此类帮助程序类可能是在 C++ 中使用的唯一合理方式friend,Java 不需要它,因为它有另一种机制。迭代器就是一个很好的例子。

于 2011-01-10T14:36:49.980 回答
3

完全同意spaceghost在他的回答中的说法

与流行观点相反,这里有很多情况,特别是对于基础设施功能,朋友访问导致更好的设计,而不是更差的设计。

我的例子很简单——如果一个类 A 必须在 java 中为类 B 提供一个特殊的“朋友”接口,我们必须将它们放在同一个包中。没有例外。在这种情况下,如果 A 是 B 的朋友并且 B 是 C 的朋友,则 A 必须是 C 的朋友,这并不总是正确的。这种“友谊传递性”打破了封装,而不是 C++ 友谊可能导致的任何问题。

于 2013-07-23T14:24:40.730 回答
2

为什么不简单地认为 Java 需要将友元类放在一起呢?包私有可见性允许同一包中的每个人访问这些成员。因此,您不仅限于明确声明的朋友,而且您允许任何(现有或未来)朋友更改一些专门为此目的设计的成员(但不是您的私人内容)。您仍然可以完全依赖封装。

于 2011-01-10T14:19:37.260 回答
2

只是添加到其他答案:

Java 中有默认的包可见性。因此,您可以调用同一包邻居中的所有类。在这种情况下,您可以明确控制向邻居显示的内容 - 只是具有包可见性的成员。

所以,它不是真正的朋友,但可以是相似的。是的,这也会导致糟糕的设计......

于 2011-01-10T14:21:22.530 回答
2

在我看来,某种朋友特性(不一定与 C++ 非常相似)在 Java 的某些情况下会非常有用。目前我们有包私有/默认访问黑客,以允许在同一个包(例如)中紧密耦合的类之间进行协作StringStringBuffer但这会打开整个包的私有实现接口。在包之间,我们有邪恶的反射黑客,这会导致一大堆问题。

在 Java 中执行此操作有一点额外的复杂性。C++ 在解决函数重载(和类似问题)时忽略访问限制 - 如果程序编译#define private public不应该做任何事情。Java(大部分)丢弃不可访问的成员。如果需要考虑友谊,则解决方案会更加复杂且不那么明显。

于 2011-01-10T16:00:08.950 回答