本文参考自Java编程思想第四版第6章,并结合自己现有知识做的一些总结。
访问控制(或隐藏具体实现)与“最初的实现不恰当”有关。
1. 访问权限控制
最最常见的类库(java.lang,java.util等伴随着JDK的类库)。
对于类库开发者来说,他需要开放一些域(方法,成员,类)给客户端程序员调用,同时也要阻止客户端程序员访问甚至修改某些域。对于这些域的控制称为访问权限控制。(绝大部分时候,我们属于客户端程序员)
对于访问权限的控制,Java提供了访问权限修饰词(public,protected,default,private),它们可用来修饰域,以此决定域能被访问的范围。
1.1 包——package
Java中提供了关键字package将一系列拥有共同的特点或合力完成某项功能的类放在一个包中。规定,包名由小写字母组成,通过英文符号’.'分隔。为了使包是全世界唯一的,建议包的名字以倒过来的域名开始,如en.edu.xtu.自定义包名,package语句必须为程序的第一句非注释语句。
问题一:
为什么平常写Java代码时,导入jdk中所包含的包可以直接运行?
当我们需要运行一个class文件时(俗称运行一个Java程序),需要到系统定义的CLASSPATH变量(文件路径)下找对应的所需要的.class文件。找到了就可以运行,找不到自然报错。我们设置的CLASSPATH变量一般为([]的内容为解释)CLASSPATH=.[当前工作目录];D:\java\jdk1.8.0_131\lib\tool.jar;D:\java\jdk1.8.0_131\lib\dt.jar[电脑上安装的jdk下的lib文件夹中的tool.jar和dt.jar,它们包括了常用的所有工具包等等]。
假如我们现在运行一个Java程序需要一个A.class文件(导包项有import A;),那么它会遍历CLASSPATH中的路径,直到找到一个CLASSPATH\A.class存在。当然如果有两个及以上的CLASSPATH中都包含A.class时,我们就不能直接简单的导入包,然后new一个A对象,而是需要这个A对象的全名。一般我们会避免这种情况的出现。
1.2 访问权限修饰词
public | protected | default | private | |
---|---|---|---|---|
同包 | 能 | 能 | 能 | 能 |
同包子类 | 能 | 能 | 能 | 不能 |
不同包子类 | 能 | 能 | 不能 | 不能 |
不同包非子类 | 能 | 不能 | 不能 | 不能 |
public所修饰的域是毫无遮挡的
平常我们使用类库开发人员开发的jar包时,只能创建其中访问权限为public的类的对象。
类库开发人员可以将其想要公开的接口设置为public,至于其具体实现可以隐藏起来。这样即可以方便自己修改完善类库,同时不印象客户端程序的运行。
protected所修饰的域可以被同包下的类和子类所访问
default修饰其实就是没有package语句的类和没有修饰词的成员变量和方法,它们默认的包为当前工作目录。
private修饰的域只能够被类本身所访问。
什么情况下可以创建某个类的对象(构造方法不是private的):
- 类是public的,同包下可以创建其对象。不同包下,需要这个类所在的包能够与某个CLASSPATH相连接,这时也可以创建其对象。
- 类是默认的,只能在同包下创建其对象。
如果我拥有这个类的对象或者是我有这个类的名字,我就一定能访问它的成员变量和方法吗?
答案是否定的,只有被合适的访问权限词修饰的字段和方法才能被访问。如public类中的默认,私有的字段和方法不能被不同包下的该类的对象访问。