Java包
◼ 随着程序架构越来越大,类的个数也越来越多,解决类的命名冲突是一件很麻烦的事情。
◼ 有时,开发人员还可能需要将处理同一方面的问题的类放在同一个目录下,以便于管理。
👇
Java 引入 包(package) 机制,提供了类的多层命名空间,用于解决类的 命名冲突、类文件管理 以及 控制访问 等问题
包允许在更广泛的范围内保护类、数据和方法。可以在包内定义类,而在包外的代码不能访问该类,这使得类之间有隐私性
包的定义:
1 | package 包名[.子包名]… ; |
Java 包的命名规则:
◼ 包名全部由小写字母(多个单词也全部小写)
◼ 如果包名包含多个层次,每个层次用 “.” 分割
◼ 包名一般由倒置的域名开头,比如 com.baidu,不要有 www
◼ 自定义包 不能用 java 开头( java.xxx.xx这种)// Java 安全机制
◼ 默认包:如果源文件没有定义包,那么类将会被放进一个无名的包中,称为默认包 (在实际开发中,通常不会把类定义在默认包下)
示例:
1 | package edu.wust.examples; |
◼ package 命令必须放在源文件的最前面
◼ 一个源文件最多只能有一条 package 命令
◼ 如果没有 package,类将会保存在当前默认包中(不推荐)
◼ 一条 package 命令对源文件中的所有类起作用
◼ 编译后的 .class 文件也按照包结构存放
导入包:
1 | import 包名[.子包名…].类名 ; |
如果是导入全部类就用”*”代替
👇
◼ import
向某个 Java 文件中导入指定包层次下的某个类或全部类(不包含子包的类)
◼ import
语句位于 package 语句之后,类定义之前
◼ 一个 Java 源文件 可以包含多个 import
语句
◼ 同一个包中类的无需 import
如果不使用 import 导入包,那么使用不同包中的其它类时,需要使用该类的全名(包名+类名):
edu.wust.examples.A a = new edu.wust.examples.A();
//比较繁琐其中,
edu.wust.examples
是包名,A
是包中的类名,a
是类的对象
注:Java默认已导入 java.lang 包下所有类,该包是 java 语言的核心,提供了很多基础类:如 String、包装类、Math、Object、Class、Thread、Exception 等类
了解:静态导入
1 | import static 包名[.子包名…].类.静态成员(变量或方法) ; |
如果是导入全部静态成员变量、方法就用”*”代替
1 | import static java.lang.System.*; // 导入System类中的全部静态成员变量和方法 |
部分系统包
包 | 说明 |
---|---|
java.lang | Java 的核心类库,包含运行 Java 程序必不可少的基础类,如 String、包装类、Math、Object、Class、Thread 线程、Exception 异常处理等类,系统默认加载这个包 |
java.io | Java语言的标准输入/输出类库,如基本输入/输出流、文件输入/输出等 |
java.util | 包含实用程序类,如 Scanner、Date、Calender、Random、数据结构(如List/Map等集合类)等。 |
java.awt | 构建图形用户界面(GUI)的类库,低级绘图操作 Graphics 类、图形界面组件和布局,以及用户界面交互控制和事件响应(如 Event 类) |
java.net | 包含执行与网络相关操作的类,如 Socket、ServerSocket、URL类等 |
java.lang.reflect | 提供用于反射对象的工具 |
java.sql | 实现 JDBC 的类库 |
java.text | 处理显示对象格式化,如 SimpleDateFormat 类等 |
访问控制
◼ 信息隐藏是 OOP 最重要的功能之一。在编写程序时,有些数据可能不希望被用户调用,需要控制这些数据的访问
◼ 访问控制:就是限定类、属性或方法是否可以被程序里的其他部分访问
👇
◼ 类的访问控制:只能是 public 或者 default (不写出来,也称 friendly)
◼ 属性和方法的访问控制有 4 个: private、default(不写)、protected 和 public
类的访问控制
◼ Java类常用访问控制有2种:public 和 default (不写出来,也称 friendly)
◼ public 类:可以在 任何一个包中 的 任何一个类 中被访问和继承
◼ default 类:只能在同一个包 中被其它类所访问和继承
成员的访问控制
包括属性和方法,作用域按大小排序:private < default < protected < public
补充一张图
访问控制说明
修饰符 | 说明 |
---|---|
private | private 成员,只能被该类自身的方法访问和修改,而不能被任何其他类(包括子类)访问和引用。因此,private 修饰符具有最高的保护级别 |
default | 如果一个类没有访问控制符,说明它具有默认的访问控制特性。这种默认的访问控制权规定,该类只能被同一个包中的类访问和引用,而不能被其他包中的类使用,即使其他包中有该类的子类 |
protected | protected 成员可以被三种类所访问:该类自身、与它在同一个包中的其他类以及在其他包中的该类的子类。使用 protected 的主要作用,是允许其他包中它的子类来访问父类的特定属性和方法,否则可以使用默认访问控制 |
public | public 成员具有被其任何类访问的可能性 (import 引入 public 类) |
访问控制测试:
◼ 情况1:类在同一个包中
1 | package edu.wust.cs; |
1 | package edu.wust.cs; |
上面两个类在同一个包中
A类修改为default类(同一包)
1 | package edu.wust.cs; |
1 | package edu.wust.cs; |
虽然去掉了 class A 的 public 访问控制符,但 Test 类中的对象依旧可以访问类 A 的非私有成员。
◼ 情况2:类在不同一个包中
1 | package edu.wust.cs; |
1 | package edu.wust.se; |
A类修改为default类(不同包)
1 | package edu.wust.cs; |
1 | package edu.wust.se; |
内部类
◼ 在类的内部可以定义另一个类。
◼ 如果在 Outer 类的内部再定义一个 Inner 类,此时 Inner 类就称为内部类(或嵌套类),而类 Outer 则称为外部类(或宿主类)
◼ 如果有多层嵌套,最外层的类称为 顶层类。
1 | class Outer { // 外部类 |
注:内部类与外部类不能重名
内部类分类
非静态内部类
◼ 在外部类的静态方法和外部类以外的其他类中,必须通过外部类的实例创建内部类的实例 ★
◼ 非静态内部类不能有静态方法、静态属性和静态代码块 ★ (以上两条见示例1)
◼ 非静态内部类可以直接访问外部类的成员,但是外部类不能直接访问非静态内部类成员 ★ (示例2、3)
Outer.java
1 | public class Outer { |
示例2 – 在非静态内部类中,可以访问外部类的所有成员
注:本例两个类都在同一包下
1 | package edu.wust.examples; |
示例3 – 非静态内部类同名变量问题
1 | public class Outer { |
内部类练习题:输出30,20,10,请填空
1 | class Outer { |
静态内部类
◼ 通常一个普通类不允许声明为静态的,只有一个内部类才可以
◼ 在创建静态内部类的实例时,不需要创建外部类的实例 ★ (示例1)
◼ 静态内部类中可以定义静态成员和实例成员 (示例2)
◼ 静态内部类可以直接访问外部类的静态成员,如果要访问外部类的实例成员,则需要通过外部类的实例 去访问 (示例3)
静态内部类示例1 – 不需外部类对象创建
1 | public class Outer { |
示例2:静态内部类中可以定义静态成员和实例成员
1 | public class Outer { |
示例3:访问外部类的成员
1 | public class Outer { |
局部内部类
◼ 局部内部类只在当前方法中有效
◼ 局部内部类不能使用 public、private 和 protected修饰
◼ 局部内部类不能使用 static 修饰符
◼ 在局部内部类中可以访问外部类的所有成员
◼ 在局部内部类中只可以访问当前方法中 final 类型的参数与变量
局部内部类示例