当前位置: 首页 > 知识库问答 >
问题:

在Java中,public、protected、package private和private之间有什么区别?

姬高扬
2023-03-14

在Java中,是否有明确的规则来规定何时使用每个访问修饰符,即默认的(包私有),公共的受保护的私有的,同时使接口处理继承?

共有3个答案

祁霖
2023-03-14

下面是该表的更好版本,其中还包括一列模块

>

  • 私有成员(i)只能在声明的同一类中访问。

    没有访问修饰符(j)的成员只能在同一个包中的类中访问。

    受保护的成员(k)可以在同一个包中的所有类以及其他包中的子类中访问。

    公共成员(l)对所有类都是可访问的(除非它位于一个模块中,该模块没有导出它声明的包)。

    访问修饰符是一个帮助您防止意外破坏封装(*)的工具。问问你自己,你是否打算让成员成为类、包、类层次结构的内部成员,或者根本不是内部成员,并相应地选择访问级别。

    例如:

    • 一个字段长的内部计数器可能应该是私有的,因为它是可变的和一个实现细节。
    • 应该只在工厂类(在同一个包中)中实例化的类应该有一个包限制构造函数,因为不可能直接从包外部调用它。
    • 应该保护在渲染前调用并在子类中用作钩子的内部空格。
    • 从GUI代码调用的空保存游戏(File dst)方法应该是公共的。

    (*)什么是封装

  • 黄磊
    2023-03-14

    (警告:我不是Java程序员,我是Perl程序员。Perl没有正式的保护,这也许就是为什么我如此理解这个问题:))

    就像你想的那样,只有声明它的类才能看到它。

    它只能被声明它的包看到和使用。这是Java中的默认设置(有些人认为这是一个错误)。

    包私有可以通过子类或包成员看到。

    每个人都能看到。

    在我控制的代码之外可见。(虽然不是Java语法,但这对本次讨论很重要)。

    C定义了一个称为“friend”的附加级别,您知道的越少越好。

    什么时候应该使用什么?整个想法是封装来隐藏信息。你想尽可能对你的用户隐藏事情是如何完成的细节。为什么?因为这样你以后就可以改变它们,而不会破坏任何人的代码。这让你可以优化、重构、重新设计和修复错误,而不用担心有人在使用你刚刚修改的代码。

    因此,经验法则是让事物只在必须的时候才可见。从private开始,只在需要时添加更多可见性。只公开用户需要知道的内容,你公开的每一个细节都会限制你重新设计系统的能力。

    如果您希望用户能够自定义行为,而不是公开内部结构,这样他们就可以覆盖它们,那么最好将这些胆量塞进一个对象中,并公开该接口。他们可以简单地插入一个新对象。例如,如果您正在编写一个CD播放器,并且希望“go find info about this CD”有点可定制,而不是公开这些方法,那么您应该将所有这些功能放在它的对象中,只公开您的对象getter/setter。通过这种方式,吝啬暴露自己的胆量会鼓励良好的构图和关注点的分离

    我坚持只使用“私有”和“公共”。许多面向对象语言就是这样。“受保护”可能很方便,但这是一种欺骗。一旦一个界面不仅仅是私有的,它就超出了你的控制范围,你必须去寻找别人的代码来找到用途。

    这就是“发布”这个概念的用武之地。改变一个接口(重构它)需要你找到所有使用它的代码,并同时改变它。如果接口是私有的,那没问题。如果它受到保护,你必须找到你所有的子类。如果它是公共的,你必须找到所有使用你代码的代码。有时这是可能的,例如,如果你正在开发仅供内部使用的公司代码,那么一个接口是否是公共的并不重要。你可以从公司存储库中获取所有代码。但是如果一个接口是“发布的”,如果有代码在你的控制之外使用它,那么你就完了。您必须支持该接口,否则就有可能破坏代码。即使是受保护的接口也可以被认为是已发布的(这就是为什么我不费心受保护)。

    许多语言发现公共/受保护/私有的等级性质太有限,不符合现实。为此,有一个特征类的概念,但那是另一场表演。

    沈骞仕
    2023-03-14

    官方教程可能对你有所帮助。

     类似资料:
    • 本文向大家介绍Java中的private、protected、public和default的区别(详解),包括了Java中的private、protected、public和default的区别(详解)的使用技巧和注意事项,需要的朋友参考一下 (1)对于public修饰符,它具有最大的访问权限,可以访问任何一个在CLASSPATH下的类、接口、异常等。它往往用于对外的情况,也就是对象或类对外的一种

    • 从一个基类派生一个类时,继承基类的方式有三种:public、protected 和 private。protected 继承和 private 继承不常用,而且使用时必须相当小心。本书中的范例都是使用 public 继承(第15章将介绍用 private 继承作为复合的另一种形式)。图 9.6 总结了每种继承中派生类对基类成员的访问性。第一列包含基类成员的访问说明符。 基类成员的访问说明符 继承类

    • 我认为在这个问题上,这是一种不同的倾向。也许这个问题更好的措辞,你什么时候会使用公共,而不是出口?从我所读到的内容来看,似乎任何C#/Java人员认为公开的地方,您实际上想要的都是导出。 您将在何时/何地使用public而不是export?

    • 问题内容: 在此示例中: 无法编译为: 而被编译器接受。 这个答案说明唯一的区别是,与不同,它允许您稍后引用类型,似乎并非如此。 是什么区别,并在这种情况下,为什么不第一编译? 问题答案: 通过使用以下签名定义方法: 并像这样调用它: 在jls§8.1.2中,我们发现(有趣的部分被我加粗了): 通用类声明定义了一组参数化类型(第4.5节), 每种可能通过类型arguments调用类型参数节的类型

    • 问题内容: 我知道一个API称为一组用于调用某些东西的函数,一个库是一个类的集合,但是像这样的包中的API实际上是什么?我可以在不使用任何API的情况下连接到类似的类,那么为什么我们称其为J2SE API而不是J2SE软件包? 问题答案: 直接来自维基百科: 在计算机科学中,应用程序编程接口(API)是定义应用程序可以从库请求服务的方式的接口 Java在那些软件包中包含许多库(Swing等),而A

    • 问题内容: 我无法理解以下文本…这是否意味着空的构造函数?为什么拥有两个不同的版本很重要? https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-2.html 在Java虚拟机级别,每个构造函数(第2.12节)都作为具有特殊名称的实例初始化方法出现。该名称由编译器提供。因为该名称不是有效的标识符,所以不能直接用Java编程语言编写的程序中使