Java访问修饰符优先级[关闭]

Posted

技术标签:

【中文标题】Java访问修饰符优先级[关闭]【英文标题】:Java access modifier priority [closed] 【发布时间】:2016-07-15 17:05:19 【问题描述】:

Java 访问修饰符隐含地赋予包优先于子类的访问权限,因为 default 修饰符允许访问包而不是子类,protected 允许访问两者,但是有没有允许访问子类但不允许访问包的修饰符。这对我来说一直很奇怪,因为我自然倾向于认为子类“更接近”父类(即使它们毕竟是它们自己的变量)然后是同一个包中的类,而且我经常发现自己处于我希望有 sub 的修饰符,而不是包的修饰符。 这可能意味着我以“错误”的方式使用包,但有人可以解释一下这个决定背后的逻辑吗?

【问题讨论】:

子类自然不会在同一个包中吗? @Gendarme 就像您的每个 Swing 应用程序最终都包含在 javax.swing 包中一样? @CoderinoJavarino 仅仅因为有人在开发一个应用程序并不意味着它是一个供外部使用的公共库。 OP 很可能正在创建一个私有项目,其中所有子类都将与 jar 一起打包。 @CoderinoJavarino 我的他们类的子类与他们自己的子类不同。为什么他们会给一个陌生人(我)访问这个类而不是他们自己开发的同一个包的类?问题似乎是,当您自己创建超类和子类时,为什么不能为希望扩展它的每个人(可能是任何人)提供该类的可访问性,而不是包的其他类。 @ClaudioP Java 访问修饰符特别缺乏表现力。试图找出它们为何如此的原因实际上没有任何意义:这是多年前指定它们的方式,如果我们坚持使用 Java,我们都会坚持下去。 25 年的事后诸葛亮是语言设计的巨大优势:/ 【参考方案1】:

当您使用 protected 修饰符时,您可以无限制地访问该类。即使该类不适合子类化,也可以随时扩展它。当您使用protected 修饰符时,您实际上是在说该类(在可预见的将来)总是适合子类化。这可能不是您想要的;例如,如果您有一个类应该为一个项目扩展几次,之后就不会再扩展了。

当您没有修饰符 (default-access/package-private) 时,您对类的访问权限有限。没有人,甚至你,都不能访问包之外的那个类,如果你正在做类似上述情况的事情,这是你想要的,其中类特定于你的项目并为任何其他任意项目扩展它将是不合适的。以下是从最高访问权限到最低访问权限的列表:

public: 无限制访问所有人和所有内容 protected:无限制访问,但限制更多 default-access:对有限数量的其他类的访问受限 private: 极其有限的访问权限:任何东西都无法访问

protected 和 default-access 之间有第五个访问修饰符,这样每个希望扩展它的类都应该可以访问它,但如果他们不想扩展它就没有访问权限是多余的,因为它已经以public abstract 的形式存在。

【讨论】:

【参考方案2】:

应用程序需要模块化,这是事实。此外,模块需要具有相互通信的手段。这两个用例是默认包和受保护包的用途。

通常,与您正在构建的模块相关的文件位于同一个包中。例如:

--my_module
 |-- MainModuleClass
 |-- HelperA
 |-- HelperB

在这种情况下,MainModuleClass 通常具有 HelperAHelperB 类型的字段,并且开发该模块的团队创建了所有 3 个类 - 因此,“他们知道自己在做什么”。此外,所有这 3 个类都有高度相关的职责——它们构成了模块的核心。由于这两个原因,它是使用“包访问”的好地方,因为您可以安全地访问彼此的类的成员。

此外,该模块的测试与模块本身在同一个包中(虽然不同的目录,但这没关系)。因此,模块的作者可以访问模块类的“默认”访问字段来读取它们的内部状态并查看内部行为是否正确。

现在,如果其他开发人员决定通过扩展其中一个类来添加一些功能,那么根据定义,该程序员就是“其他”程序员。他不知道代码以及创建原始组件的第一个团队。因此,某些字段被标记为“受保护”,仅向想要扩展代码并感到安全的“外部人员”提供访问权限。

总结一下:

    如果您正在构建一个模块并希望某些字段只能由模块中的类使用 - 默认可见性是可行的方法。 如果某些字段要扩展或由其他可能想要重用您的模块的团队使用 - 这些字段将受到保护。

【讨论】:

以上是关于Java访问修饰符优先级[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

为啥Java限制隐藏方法的访问修饰符[关闭]

受保护和没有访问修饰符之间的区别[关闭]

Java_修饰符详解

Java 访问权限修饰符 与 非访问权限修饰符

在Java和c#中如果不写访问修饰符,类和类成员默认的是啥访问修饰符?

Java中成员属性默认访问修饰符是啥