在Java中,在创建类和接口以及处理继承时,是否有明确的规则来确定何时使用每个访问修饰符,即默认的(包私有)、公共的、受保护的和私有的?
当前回答
David的回答提供了每个访问修饰符的含义。至于何时使用每一个,我建议公开所有用于外部使用的类和每个类的方法(其API),并将其他所有内容私有化。
随着时间的推移,您将了解何时将某些类包设为私有,以及何时声明某些方法受保护以便在子类中使用。
其他回答
(注意:我不是一个Java程序员,我是一个Perl程序员。Perl没有正式的保护措施,这也许就是为什么我如此理解这个问题的原因:)
私有的
就像你想的那样,只有声明它的类才能看到它。
包专用
它只能由声明它的包看到和使用。这是Java中的默认设置(有些人认为这是错误的)。
受保护的
包Private+可以由子类或包成员看到。
平民的
每个人都能看到。
出版
在我控制的代码之外可见。(虽然不是Java语法,但这对本次讨论很重要)。
C++定义了一个称为“朋友”的附加级别,你对它了解得越少越好。
你什么时候应该用什么?整个想法是封装以隐藏信息。您希望尽可能地向用户隐藏某些操作的细节。为什么?因为这样你以后就可以更改它们,而不会破坏任何人的代码。这使您可以优化、重构、重新设计和修复错误,而不用担心有人在使用您刚刚大修过的代码。
因此,经验法则是让事物尽可能地可见。从私密开始,只在需要时增加更多的可见性。只公开用户需要知道的信息,你公开的每一个细节都限制了你重新设计系统的能力。
如果您希望用户能够自定义行为,而不是将内部公开以便他们可以覆盖它们,那么通常最好将这些内容插入到对象中并将接口公开。这样他们就可以简单地插入一个新对象。例如,如果您正在编写一个CD播放器,并希望“go find info about this CD”位可定制,而不是将这些方法公开,那么您应该将所有这些功能放入其对象中,并仅将对象getter/setter公开。通过这种方式,吝啬于暴露自己的内心会鼓励良好的组合和关注的分离
我只坚持“私人”和“公共”。许多OO语言都有这一点。“受保护”可能很方便,但这是一个骗局。一旦一个接口超过了私有,它就超出了你的控制范围,你必须去查看其他人的代码才能找到用途。
这就是“发布”的概念所在。更改接口(重构它)需要找到使用它的所有代码并进行更改。如果接口是私有的,那么没问题。如果它受到保护,你必须找到所有的子类。如果它是公开的,你必须找到使用你的代码的所有代码。有时这是可能的,例如,如果您正在编写仅供内部使用的公司代码,那么接口是否公开无关紧要。您可以从公司存储库中获取所有代码。但是,如果一个接口被“发布”,如果有代码在您的控制之外使用它,那么您将被罚款。您必须支持该接口,否则可能会破坏代码。即使是受保护的接口也可以被认为是已发布的(这就是为什么我不关心受保护的)。
许多语言发现公共/受保护/私有的等级性质过于局限,不符合现实。为此,有一种特质类的概念,但这是另一种表现。
私人:仅限上课
默认值(无修饰符):对类和包的访问受限
受保护:对类、包和子类的访问受限(包内部和外部)
公共:可访问类、包(所有)和子类。。。简而言之,无处不在。
当你想到访问修饰符时,你可以这样想(适用于变量和方法):
public-->可从任何位置访问private-->只能在声明它的同一类中访问
现在,当涉及到默认和受保护时,就会出现混乱
默认-->不存在访问修饰符关键字。这意味着它严格在类的包中可用。在该包之外,任何地方都无法访问。
protected-->略低于默认值,并且除了相同的包类之外,它可以由声明的包之外的子类访问。
David的回答提供了每个访问修饰符的含义。至于何时使用每一个,我建议公开所有用于外部使用的类和每个类的方法(其API),并将其他所有内容私有化。
随着时间的推移,您将了解何时将某些类包设为私有,以及何时声明某些方法受保护以便在子类中使用。
____________________________________________________________________
| highest precedence <---------> lowest precedence
*———————————————+———————————————+———————————+———————————————+———————
\ xCanBeSeenBy | this | any class | this subclass | any
\__________ | class | in same | in another | class
\ | nonsubbed | package | package |
Modifier of x \ | | | |
————————————————*———————————————+———————————+———————————————+———————
public | ✔ | ✔ | ✔ | ✔
————————————————+———————————————+———————————+———————————————+———————
protected | ✔ | ✔ | ✔ | ✘
————————————————+———————————————+———————————+———————————————+———————
package-private | | | |
(no modifier) | ✔ | ✔ | ✘ | ✘
————————————————+———————————————+———————————+———————————————+———————
private | ✔ | ✘ | ✘ | ✘
____________________________________________________________________
推荐文章
- “比较法违反其总合同!”
- 从Java项目生成UML类图
- 正确地从一个<Integer>的列表中移除一个整数
- Java开关语句:需要常量表达式,但它是常量
- Java的assertEquals方法可靠吗?
- 如何在Java中获得系统变量值?
- 比较Java中2个XML文档的最佳方法
- Java SE 8有对或元组吗?
- Java 8流的.min()和.max():为什么编译?
- 生成1和10之间的随机数Java
- 我如何从资产文件夹解析一个本地JSON文件到一个ListView?
- 将枚举转换为集合/列表
- 在Java中创建对象数组
- Java中字符串的字节数
- IntelliJ IDEA with Junit 4.7”!!JUnit 3.8或更高版本: