问题

在Java中,在使用classinterface并处理继承时,是否存在何时使用每个访问修饰符的明确规则,即默认(package private),publicprotectedprivate


#1 热门回答(4560 赞)

The official tutorial可能对你有一些用处。

│ Class │ Package │ Subclass │ Subclass │ World
            │       │         │(same pkg)│(diff pkg)│ 
────────────┼───────┼─────────┼──────────┼──────────┼────────
public      │   +   │    +    │    +     │     +    │   +     
────────────┼───────┼─────────┼──────────┼──────────┼────────
protected   │   +   │    +    │    +     │     +    │         
────────────┼───────┼─────────┼──────────┼──────────┼────────
no modifier │   +   │    +    │    +     │          │    
────────────┼───────┼─────────┼──────────┼──────────┼────────
private     │   +   │         │          │          │    

+ : accessible
blank : not accessible

#2 热门回答(352 赞)

(注意:我不是Java程序员,我是Perl程序员,Perl没有正式的保护措施,这也许是为什么我理解这个问题的原因:))

## 私人的

就像你会想的那样,只有宣布它的可以看到它。

##包私密

只能在5222281364程序包**中看到并使用它。这是Java中的默认值(有些人认为是错误的)。

##受保护

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

## 上市

每个人都可以看到它。

##发布

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

C定义了一个名为“朋友”的附加级别,你知道的越少越好。

你什么时候该用什么?整个想法是隐藏信息的封装。尽可能多地隐藏你的用户完成某些事情的细节。为什么?因为那样你可以稍后改变它们而不会破坏任何人的代码。这使您可以优化,重构,重新设计和修复错误,而无需担心有人正在使用您刚刚彻底检查过的代码。

所以,经验法则是让事物看起来像他们必须的那样。从私有开始,只根据需要添加更多可见性。只公开那些对用户来说绝对必要的知识,你公开的每一个细节都会激发你重新设计系统的能力。

如果您希望用户能够自定义行为,而不是将内部公开,以便他们可以覆盖它们,那么将这些内容推入对象并使该接口公开通常是一个更好的主意。这样他们可以简单地插入一个新的对象。例如,如果您正在编写CD播放器并希望“查找有关此CD的信息”位可自定义,而不是将这些方法公开,您可以将所有功能放入其自己的对象中并使公共getter / setter成为公共对象。以这种方式吝啬暴露你的胆量鼓励良好的成分和关注点的分离

就我个人而言,我坚持“私人”和“公众”。许多OO语言就是这样。 “受保护”可以很方便,但它确实是一个骗子。一旦界面不仅仅是私人的,它就在你的控制之外,你必须去寻找其他人的代码才能找到用途。

这就是“发布”这个概念的来源。改变一个接口(重构它)需要你找到所有使用它的代码并改变它。如果界面是私人的,那么没问题。如果它受到保护,则必须去查找所有的子类。如果它是公开的,你必须找到所有使用你的代码的代码。有时候这是可能的,例如,如果您正在处理仅供内部使用的公司代码,则无论接口是否公开都无关紧要。您可以从公司存储库中获取所有代码。但是如果一个接口是“发布”的,如果有代码在你的控制之外使用它,那么你就会被洗脑。您必须支持该接口或冒险破坏代码。即使受保护的接口也可以被认为是公开的(这就是为什么我不打扰受保护的原因)。

许多语言认为公共/保护/私人的等级性太过于限制,不符合现实。为此,有atrait class的概念,但这是另一个节目。


#3 热门回答(235 赞)

这是更好的表格。 (未来证明与模块专栏。)

Java Access Modifiers

##解释

  • 私有成员只能在声明的同一个类中访问。
  • 没有访问修饰符的成员只能在同一个包中的类中访问。
  • 受保护的成员可以在同一包中的所有类中访问,也可以在其他包中的子类内访问。
  • 所有类都可以访问公共成员(除非它驻留在不导出声明包的模块中)。

##选择哪个修饰符?

访问修饰符是帮助您防止意外破坏封装(*)的工具。问问你自己是否打算让这个成员成为班级,包裹,班级层次内部或根本不在内部的东西,并相应地选择访问级别。
示例:-字段long internalCounter可能应该是私有的,因为它是可变的并且是实现细节。

  • 一个只能在工厂类中实例化的类(在同一个包中)应该有一个包限制的构造函数,因为它不应该直接从包之外调用它。
  • 在渲染之前调用的内部无效beforeRender()方法被用作子类中的钩子,应该受到保护。
  • 从GUI代码中调用的void saveGame(File dst)方法应该是公开的。
    (*)What is Encapsulation exactly?

原文链接