在Java中,public、protected、package-private和private有什么区别?
在Java中,public、protected、package-private和private有什么区别?
在Java中,对于每个访问修饰符(默认的(包私有)、public
、protected
和private
),在创建class
和interface
,以及处理继承时,是否有明确的规定需要使用哪些访问修饰符?
(注意:我不是Java程序员,我是Perl程序员。Perl没有正式的保护机制,这也许是我很好地理解这个问题的原因 :))
私有的
就像你想的那样,只有声明它的类可以看到它。
包私有的
只能被声明它的包看到和使用。这是Java中的默认设置(有些人认为这是一个错误)。
受保护的
包私有 + 可以被子类或包成员看到。
公共的
所有人都可以看到它。
发布的
在我所控制的代码之外可见。(虽然不是Java语法,但在这个讨论中很重要)。
C++定义了一个称为“友元(friend)”的额外级别,你知道得越少越好。
什么时候应该使用什么?整个想法就是封装隐藏信息。尽可能地,你希望从用户那里隐藏如何完成某件事的细节。为什么?因为这样你就可以稍后更改它们而不破坏任何人的代码。这使你可以优化、重构、重新设计和修复错误,而不用担心有人在使用你刚刚大修的代码。
因此,经验法则是只让事物尽可能可见。从 private 开始,只在需要时增加更多可见性。只有必须让用户知道的内容才公开,每个你公开的细节都会限制你重新设计系统的能力。
如果你希望用户能够自定义行为,而不是将内部公开以便他们可以重写它们,将那些内部部分放入一个对象中,并将该接口公开通常是一个更好的主意。这样他们可以简单地插入一个新对象。例如,如果你正在编写 CD 播放器,并希望 "查找有关此 CD 的信息" 部分可定制化,而不是使这些方法公开,你会将所有那些功能都放入其对象中,并使你的对象 getter/setter 公开。以这种方式对暴露你的内部进行吝啬鼓励良好的组合和关注点分离。
我只使用 "private" 和 "public"。许多面向对象的语言只有这两个关键字。"Protected" 可能很方便,但它是一个欺骗。一旦一个接口超过了私有范围,它就在你的控制范围之外,你必须去查找其他人的代码来找到使用情况。
这就是“published”这个概念的来源。更改接口(重构它)需要找到所有正在使用它的代码并进行更改。如果接口是私有的,那么没有问题。如果是受保护的,你必须去找到所有的子类。如果是公共的,你必须去找到使用你的代码的所有代码。有时这是可能的,例如,如果你正在为内部使用的企业代码工作,接口是公共的并不重要。你可以从公司代码库中获取所有代码。但如果一个接口是“published”,如果有在你的控制之外使用它的代码,那么你就完了。你必须支持该接口,否则就会破坏代码。即使是受保护的接口也可以被认为是“published”(这就是为什么我不使用受保护的原因)。
许多编程语言发现公共/受保护/私有的分层结构太过限制且不符合实际情况。因此,有了“特质类”(trait class)的概念,但这是另一个话题。
官方教程可能对您有所帮助。
Class | Package | Subclass (同一pkg) |
Subclass (不同pkg) |
World | |
---|---|---|---|---|---|
public |
+ | + | + | + | + |
protected |
+ | + | + | + | |
无修饰符 | + | + | + | ||
private |
+ |
+ : 可访问
空白 : 不可访问