在Java中,在创建类和接口以及处理继承时,是否有明确的规则来确定何时使用每个访问修饰符,即默认的(包私有)、公共的、受保护的和私有的?
当前回答
简而言之
公共:随处可见。protected:可由同一包的类和驻留在任何包中的子类访问。默认(未指定修饰符):可由同一包的类访问。private:只能在同一类中访问。
其他回答
David的回答提供了每个访问修饰符的含义。至于何时使用每一个,我建议公开所有用于外部使用的类和每个类的方法(其API),并将其他所有内容私有化。
随着时间的推移,您将了解何时将某些类包设为私有,以及何时声明某些方法受保护以便在子类中使用。
这一切都是关于封装的(或者正如乔·菲利普斯所说的,最起码的知识)。
从限制性最大的(私有)开始,看看以后是否需要限制性较小的修饰符。
我们都使用方法和成员修饰符,如private、public、。。。但很少有开发人员会做的一件事是使用包来逻辑地组织代码。
例如:您可以将敏感的安全方法放在“安全”包中。然后放一个公共类,它访问这个包中的一些安全相关代码,但保持其他安全类包的私有性。因此,其他开发人员只能在这个包之外使用公开可用的类(除非他们更改了修饰符)。这不是安全功能,但将指导使用。
Outside world -> Package (SecurityEntryClass ---> Package private classes)
另一件事是,相互依赖性很强的类最终可能会出现在同一个包中,如果依赖性太强,最终可能会被重构或合并。
相反,如果您将所有内容都设置为公共,则不清楚哪些内容应该访问或不应该访问,这可能会导致编写大量javadoc(它不会通过编译器强制执行任何内容…)。
官方教程可能对您有所帮助。
Class | Package | Subclass (same pkg) |
Subclass (diff pkg) |
World | |
---|---|---|---|---|---|
public |
+ | + | + | + | + |
protected |
+ | + | + | + | |
no modifier | + | + | + | ||
private |
+ |
+:可访问空白:不可访问
当谈到访问修饰符时,我们很容易理解,非常简单的规则包括它们。
专用访问修饰符用于:-仅同一类
默认Access修饰符用于:-仅同一类/同一包子类
Protected Access修饰符用于:-同一类/同一包子类/同包非子类/不同包子类
公共访问修饰符用于:-我们可以在任何地方使用(相同的类/相同的包子类/相同包非子类/不同的包子类别/不同包非子类别)
私有的
方法、变量和构造函数
声明为私有的方法、变量和构造函数只能在声明的类本身内访问。
类和接口
专用访问修饰符是限制性最强的访问级别。类和接口不能是私有的。
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
推荐文章
- 在流中使用Java 8 foreach循环移动到下一项
- 访问限制:'Application'类型不是API(必需库rt.jar的限制)
- 用Java计算两个日期之间的天数
- 如何配置slf4j-simple
- 在Jar文件中运行类
- 带参数的可运行?
- 我如何得到一个字符串的前n个字符而不检查大小或出界?
- 我可以在Java中设置enum起始值吗?
- Java中的回调函数
- c#和Java中的泛型有什么不同?和模板在c++ ?
- 在Java中,流相对于循环的优势是什么?
- Jersey在未找到InjectionManagerFactory时停止工作
- 在Java流是peek真的只是调试?
- Recyclerview不调用onCreateViewHolder
- 将JSON字符串转换为HashMap