在Java中,在创建类和接口以及处理继承时,是否有明确的规则来确定何时使用每个访问修饰符,即默认的(包私有)、公共的、受保护的和私有的?
当前回答
区别可以在已经提供的链接中找到,但使用哪一个链接通常取决于“最少知识原则”。只允许所需的最小可见性。
其他回答
(注意:我不是一个Java程序员,我是一个Perl程序员。Perl没有正式的保护措施,这也许就是为什么我如此理解这个问题的原因:)
私有的
就像你想的那样,只有声明它的类才能看到它。
包专用
它只能由声明它的包看到和使用。这是Java中的默认设置(有些人认为这是错误的)。
受保护的
包Private+可以由子类或包成员看到。
平民的
每个人都能看到。
出版
在我控制的代码之外可见。(虽然不是Java语法,但这对本次讨论很重要)。
C++定义了一个称为“朋友”的附加级别,你对它了解得越少越好。
你什么时候应该用什么?整个想法是封装以隐藏信息。您希望尽可能地向用户隐藏某些操作的细节。为什么?因为这样你以后就可以更改它们,而不会破坏任何人的代码。这使您可以优化、重构、重新设计和修复错误,而不用担心有人在使用您刚刚大修过的代码。
因此,经验法则是让事物尽可能地可见。从私密开始,只在需要时增加更多的可见性。只公开用户需要知道的信息,你公开的每一个细节都限制了你重新设计系统的能力。
如果您希望用户能够自定义行为,而不是将内部公开以便他们可以覆盖它们,那么通常最好将这些内容插入到对象中并将接口公开。这样他们就可以简单地插入一个新对象。例如,如果您正在编写一个CD播放器,并希望“go find info about this CD”位可定制,而不是将这些方法公开,那么您应该将所有这些功能放入其对象中,并仅将对象getter/setter公开。通过这种方式,吝啬于暴露自己的内心会鼓励良好的组合和关注的分离
我只坚持“私人”和“公共”。许多OO语言都有这一点。“受保护”可能很方便,但这是一个骗局。一旦一个接口超过了私有,它就超出了你的控制范围,你必须去查看其他人的代码才能找到用途。
这就是“发布”的概念所在。更改接口(重构它)需要找到使用它的所有代码并进行更改。如果接口是私有的,那么没问题。如果它受到保护,你必须找到所有的子类。如果它是公开的,你必须找到使用你的代码的所有代码。有时这是可能的,例如,如果您正在编写仅供内部使用的公司代码,那么接口是否公开无关紧要。您可以从公司存储库中获取所有代码。但是,如果一个接口被“发布”,如果有代码在您的控制之外使用它,那么您将被罚款。您必须支持该接口,否则可能会破坏代码。即使是受保护的接口也可以被认为是已发布的(这就是为什么我不关心受保护的)。
许多语言发现公共/受保护/私有的等级性质过于局限,不符合现实。为此,有一种特质类的概念,但这是另一种表现。
私有的
方法、变量和构造函数
声明为私有的方法、变量和构造函数只能在声明的类本身内访问。
类和接口
专用访问修饰符是限制性最强的访问级别。类和接口不能是私有的。
Note
如果类中存在公共getter方法,则可以在类外部访问声明为私有的变量。在超类中声明为受保护的变量、方法和构造函数只能由其他包中的子类或受保护成员类的包中的任何类访问。
受保护的
类和接口
受保护的访问修饰符不能应用于类和接口。
方法、字段可以声明为受保护,但接口中的方法和字段不能声明为受。
Note
受保护的访问使子类有机会使用helper方法或变量,同时防止非相关类尝试使用它。
平民的
声明为公共的类、方法、构造函数、接口等可以从任何其他类访问。
因此,可以从属于Java Universe的任何类访问在公共类中声明的字段、方法和块。
不同的软件包
但是,如果我们试图访问的公共类位于不同的包中,那么仍然需要导入公共类。
由于类继承,类的所有公共方法和变量都由其子类继承。
默认-无关键字:
默认访问修饰符意味着我们不为类、字段、方法等显式声明访问修饰符。
在相同的软件包中
没有任何访问控制修饰符的变量或方法可用于同一包中的任何其他类。接口中的字段是隐式的公共静态final,接口中的方法默认是公共的。
Note
我们无法覆盖静态字段。如果尝试覆盖,则不会显示任何错误但除了我们之外,它不起作用。
相关答案
重写java中的静态方法
参考链接
http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.htmlhttp://www.tutorialspoint.com/java/java_access_modifiers.htm
当你想到访问修饰符时,你可以这样想(适用于变量和方法):
public-->可从任何位置访问private-->只能在声明它的同一类中访问
现在,当涉及到默认和受保护时,就会出现混乱
默认-->不存在访问修饰符关键字。这意味着它严格在类的包中可用。在该包之外,任何地方都无法访问。
protected-->略低于默认值,并且除了相同的包类之外,它可以由声明的包之外的子类访问。
这一切都是关于封装的(或者正如乔·菲利普斯所说的,最起码的知识)。
从限制性最大的(私有)开始,看看以后是否需要限制性较小的修饰符。
我们都使用方法和成员修饰符,如private、public、。。。但很少有开发人员会做的一件事是使用包来逻辑地组织代码。
例如:您可以将敏感的安全方法放在“安全”包中。然后放一个公共类,它访问这个包中的一些安全相关代码,但保持其他安全类包的私有性。因此,其他开发人员只能在这个包之外使用公开可用的类(除非他们更改了修饰符)。这不是安全功能,但将指导使用。
Outside world -> Package (SecurityEntryClass ---> Package private classes)
另一件事是,相互依赖性很强的类最终可能会出现在同一个包中,如果依赖性太强,最终可能会被重构或合并。
相反,如果您将所有内容都设置为公共,则不清楚哪些内容应该访问或不应该访问,这可能会导致编写大量javadoc(它不会通过编译器强制执行任何内容…)。
私人:仅限上课
默认值(无修饰符):对类和包的访问受限
受保护:对类、包和子类的访问受限(包内部和外部)
公共:可访问类、包(所有)和子类。。。简而言之,无处不在。
推荐文章
- 到底是什么导致了堆栈溢出错误?
- 为什么Android工作室说“等待调试器”如果我不调试?
- Java:路径vs文件
- ExecutorService,如何等待所有任务完成
- Maven依赖Servlet 3.0 API?
- 如何在IntelliJ IDEA中添加目录到应用程序运行概要文件中的类路径?
- getter和setter是糟糕的设计吗?相互矛盾的建议
- Android room persistent: AppDatabase_Impl不存在
- Java的String[]在Kotlin中等价于什么?
- Intellij IDEA上的System.out.println()快捷方式
- 使用Spring RestTemplate获取JSON对象列表
- Spring JPA选择特定的列
- URLEncoder不能翻译空格字符
- Java中的super()
- 如何转换JSON字符串映射<字符串,字符串>与杰克逊JSON