Java 之路 (六) -- 访问权限控制(Package、Public、protected、friendly、private)
这一章内容比较少,也比较基础。
不多废话,下面开始这一章的学习吧。
学习内容
- 包 package
- 访问权限 public、protected、默认、private
1. Package
(1) 原因:为了更好的组织类,Java 提供了包机制,用来区别类名的命名空间。
(2) 包的作用:
- 利用操作系统的层次化的文件结构,将特定包的 .class 文件都置于一个目录下。
- 包创建了新的命名空间,解决命名冲突问题。
- 便于查找目录结构中的类
- 将 package 分解为机器上的某个目录,当 Java 程序运行需要加载 .class 文件的时候,可以确定 .class 文件再目录上所处的位置。
- 将构件捆绑到一个内聚的类库单元。
- 限定了访问权限,访问权限修饰词得以起到作用。
(3) 代码组织
- 编写 Java 源代码文件时,此文件被称为编译/转译单元。每个编译单元都必须有一个后缀名 .java ,而在编译单元内则必须有且仅有一个 public 类,名称与文件名称一致(不包括后缀 .java)。该编译单元里的其他非 public 类通常用来为 public 类提供支持。
- 编译 .java 文件时,其中的每个类都会有一个输出文件,名称与类的名称相同,附加后缀 .class,因此少量 .java 文件编译会得到大量 .class 文件。Java 的程序是一组可以打包并压缩为一个 JAR 的 .class 文件。Java 解释器负责这些文件的查找、装载和解释。
- 类库实际上述一组类文件。其中每个文件都有一个 public 类,以及任意数量的非 public 类。因此每个文件都有一个构件。通过 package 关键字,使得这些构建从属于同一个群组。
(4) 包的使用
-
声明所属包 – package 语句必须是文件的第一行非注释程序代码
//格式如下: package pkg1[.pkg2[.pkg3...]]; // eg. // 声明 Book 类位于 com.whdalive.simple 这个包下 package com.whdalive.simple; public class Book{ public void show(){ //... } }
-
导入 – import 关键词,仅仅位于 package 语句之后
- 只有导入相关包/类之后,才能访问其中的方法/类(视访问权限而定)
//格式如下 package pkg..; import pkg1[[.pkg2[.pkg3...]]]; // eg. package com.example; import java.util.ArrayList;// 导入了 java.util.ArrayList 这个类 // 也可以写成这样: import java.util.*; // 导入整个 java.util 包,自然包括 ArrayList 这个类。 public class ExampleImport{ ArrayList list = new ArrayList(); }
(5) Java 解释器的运行过程
首先解释一下 Java 解释器的概念:
解释器是Java虚拟机非常重要的一部分,它的工作就是把字节码转化为机器码并在特定的平台进行运行
- 找出环境变量 CLASSPATH(可以通过操作系统设置,也可不用设置,一般编译环境会为你设置)CLASSPATH 包含一个或多个目录,用来查找.class文件的根目录。
- 需要从根目录进行查询,解释器获取包的名称,将点号替换为反斜杠,具体哪种反斜杠视操作系统而定。
- 将得到的路径与 CLASSPATH 中的各个不同的项相连接,解释器就在这些目录中查找与你创建的类名称相关的 .class 文件。
(6) 包的实际用处 - 我们通过使用包来干些什么?
- 定制我们自己的工具包 – 将重复使用的工具类打包在一起,简化开发
- 内聚功能模块 – 将同一个功能模块的类打包在一起,同样是为了简化开发。
- …
2. Java 访问权限
关于继承,在下一章会介绍。
(1) 四种访问权限:
- public:接口访问权限。Java语言中访问限制最宽的修饰符。被其修饰的类、属性以及方法不仅可以跨类访问,而且允许跨包访问。
- protected:继承访问权限。介于public 和 private 之间的一种访问修饰符。被其修饰的属性以及方法只能被类本身的方法及子类访问,即使子类在不同的包中也可以访问。
- 默认:包访问权限。即不加任何访问修饰符。该模式下,只允许在同一个包中进行访问。
- private:私有访问权限。Java语言中对访问权限限制的最窄的修饰符,一般称之为“私有的”。被其修饰的属性以及方法只能被该类的对象访问,其子类不能访问,更不能允许跨包访问。
注意:关于 protected 允许子类访问这一点
子类可以直接访问父类 protected 的属性/方法,但是不能通过父类的实例对象来访问父类的属性/方法。
实际上可以理解为 子类继承了父类的 protected 方法,与其说”父类的 protected 方法被子类访问”,不如说”子类访问了 从父类那里继承而来的 protected 方法”。通过继承,子类也拥有了该 protected 方法,所以变相就是子类访问了”自己的方法”。
结论:
权限 | 类内 | 同包 | 不同包子类 | 不同包非子类 |
---|---|---|---|---|
private | √ | × | × | × |
默认 | √ | √ | × | × |
protected | √ | √ | √ | × |
public | √ | √ | √ | √ |
(2) 封装
- 指将数据和方法包装进类里,以及具体实现的隐藏(也称就是 访问权限的控制)。
(3) 访问权限控制将权限的边界划在数据类型的内部,两个原因:
-
设定客户端程序员可以使用和不可以使用的界限。
说白了就是使用户不要触碰那些他们不该触碰的部分,只提供给他们能实现的功能,而非实现细节。
-
将接口和具体实现进行分离。
类库设计者设计一个功能模块,在底层进行实现,而只对客户端程序员暴露出接口,客户端程序员通过调用该接口即可使用该功能。
严格将接口和实现进行分离后,类库设计者就可以随意更改类的内部工作方式(出于某种目的,比如提高效率),而不影响客户端程序员的使用,实现方式改变,但接口不变。
总结
这一章内容很少,大体上就是类和类库的关系,其中有两点:
- 类如何打包到类库中,结构如何
- 如何控制访问的权限
基本就是些概念的东西,但是如何在实际中有良好的使用才是关键所在。
本章结束,共勉。