为什么包可见性优先于子类可见性?

2022-09-03 15:14:27

这个答案显示了Java的可见性修饰符及其含义:

Modifier    | Class | Package | Subclass | World
————————————+———————+—————————+——————————+———————
public      |  y    |    y    |    y     |   y
————————————+———————+—————————+——————————+———————
protected   |  y    |    y    |    y     |   n
————————————+———————+—————————+——————————+———————
no modifier |  y    |    y    |    n     |   n
————————————+———————+—————————+——————————+———————
private     |  y    |    n    |    n     |   n

我的问题是,为什么允许对所有子类的可见性意味着您必须为包中的所有其他类提供可见性?换句话说,为什么Java的创建者会这样,而不是:

Modifier    | Class | Subclass | Package | World
————————————+———————+—————————-+——————————+———————
public      |  y    |    y    |    y     |   y
————————————+———————+—————————+——————————+———————
no modifier |  y    |    y    |    y     |   n
————————————+———————+—————————+——————————+———————
protected   |  y    |    y    |    n     |   n
————————————+———————+—————————+——————————+———————
private     |  y    |    n    |    n     |   n

答案 1

一个包应该由同一个团队编写和维护;在包中具有更宽松的访问控制是可以的,假设程序员对所有代码都有深入的了解。

子类通常由其他人编写;对 API 进行更严格的约束会更好。


答案 2

因为像你建议的那样,反过来在实践中是没有意义的(我承认这并不那么明显)。

假设您有一个包,其中包含一个用于客户端(第三方,其他团队等)扩展的基类,以及与基类交互的其他类(在同一包中)。这是一个非常普遍的情况。

现在,基类可能包含供包中提供的代码使用的成员/方法,但这些成员/方法对于扩展该类的客户端来说是不可访问的。

使用现在的包私有(默认)修饰符来说,这很简单,但是如果您切换强度,则不可能。您将失去向孩子课程隐藏内容的能力,同时仍然将它们提供给包装中的同伴。