包
package
包,对应 Java 源文件的目录结构,在不同的包中,可以存放两个同名的类而不冲突
在 Java 中,用 package
语句说明一个包时,该包的层次结构必须是与文件目录的层次相同
包的命名
- 包名由小写字母组成,不能以圆点开头或者结尾
- 包名之前最好加上唯一的前缀,通常使用组织倒置的网络域名
- 包名后续部分,依照不同结构内部的规范而不同
包的作用
- 允许类组成较小的单元(类似文件夹),易于找到和使用相应的文件
- 防止命名冲突,区分名字相同的类
- 有助于实施访问权限控制
import
导包
为了使用不在同一个包中的类,需要在 Java 程序中使用 import
关键字导入这个类
import 包名.类名;
// 例如
import java.util.*; // 导入 java.util 包中的所有类
import com.huawei.example.Book; // 导入指定包(可以是自定义包)中的指定类
注意事项
- 一个类同时引用了两个来自不同包的同名类,必须通过 完整的类名(包括包名在内的类名) 来区分
- 每个包都是独立的,顶层包不会包含子包的类
package
和import
的顺序是固定的package
必须位于第一行(不包括注释行)- 只允许有一个
package
- 其次是
import
- 接着是类的声明
内部类
在 Java 中,允许在一个类的内部定义类,这样的类称为 内部类,这个内部类所在的类称为 外部类
- 内部类分为:
- 成员内部类
- 局部内部类
- 静态内部类
- 匿名内部类
成员内部类
在一个类中除了可以定义成员变量、成员方法,还可以定义类,这种类称为 成员内部类
在成员内部类中,可以访问外部类的所有成员,包括成员变量和成员方法;
在外部类中,同样可以访问成员内部类的变量和方法
创建内部类对象的具体语法格式:
外部类名.内部类名 变量名 = new 外部类名().new 内部类名();
局部内部类
局部内部类,也叫做 方法内部类,就是定义在某个局部范围中的类,与局部变量一样,都是在方法中定义的,其有效范围只限于方法内部
在局部内部类中,局部内部类可以访问外部类的所有成员变量和方法;
而局部内部中的变量和方法只能在创建该局部内部类的方法中进行访问
静态内部类
所谓静态内部类,就是使用 static
关键字修饰的成员内部类
静态内部类在成员内部类前增加了 static
关键字,在功能上,静态内部类中只能访问外部类的静态成员;
通过外部类访问静态内部类成员时,可以跳过外部类从而直接通过内部类访问静态内部类成员
创建静态内部类对象的具体语法格式:
外部类名.静态内部类名 变量名 = new 外部类名.静态内部类名();
匿名内部类
匿名内部类就是没有名称的内部类
在调用包含有接口类型参数的方法时,为了简化代码,可以直接通过匿名内部类的形式传入一个接口类型参数,在匿名内部类中直接完成方法的实现
创建匿名内部类对象的具体语法格式:
new 父接口() {
// 匿名内部类实现部分
}
接口
接口技术用于描述类具有什么功能,但并不给出具体实现,类要遵从接口描述的统一规则进行定义,所以接口是对外提供的一组规则、标准。
- 面向接口编程:
- 关心实现类有何能力,而不关心实现细节
- 面向接口进行约定而不考虑接口的具体实现
接口的定义
定义接口使用关键字 interface
[修饰符] interface 接口名 [extends 父接口1, 父接口2, ...]
{
[public] [static] [final] 常量类型 常量名 = 常量值;
[public] [abstract] 方法返回值类型 方法名([参数列表]);
[public] default 方法返回值类型 方法名([参数列表]) {
// 默认方法可以有多个
// 默认方法的方法体
}
// 静态方法可以通过 接口.方法名 直接调用
[public] static 方法返回值类型 方法名([参数列表]) {
// 静态方法可以有多个
// 静态方法(类方法)的方法体
}
}
类和接口是实现关系,用 implements
表示
class 类名 implements 接口名
接口的特点
-
接口不能实例化
通过多态的方式实例化子类对象 -
接口的子类(实现类)
可以是抽象类,也可以是普通类
接口继承关系的特点
-
接口与接口之间的关系
继承关系,可以多继承
格式:
接口 extends 接口1, 接口2, 接口3...
-
继承与实现的区别
继承体现的是is a
的关系,父类中定义共性的内容
实现体现的是has a
的关系,接口中定义扩展功能
接口成员的特点
接口成员变量的特点
接口没有成员变量,只有公有的、静态的常量:
public static final 常量名 = 常量值;
接口成员方法的特点
JDK7
及以前,公有的、抽象的方法:
public abstract 返回值类型 方法名();
JDK8
以后,可以有默认方法和静态方法(可以有方法体,且可以有多个):
public default 返回值类型 方法名() {}
JDK9
以后,可以有私有方法:
private 返回值类型 方法名() {}
接口构造方法的特点
-
接口不能实例化,也没有需要初始化的成员,所以 接口没有构造方法
-
接口继承接口使用
extends
,接口允许多继承 -
实现接口使用
implements
,且必须实现接口中的所有抽象方法 -
接口是允许多实现的,即,
implements
后面可以跟多个接口,接口之间使用,
分隔
抽象类
当父类默认的 a 方法
已经过时,所有子类都需要重写,所以父类的 a 方法
的方法体是没有意义的
但是,每个子类都需要拥有 a 方法
,则可以将父类的 a 方法
定义成抽象方法,将父类定义成抽象类
抽象类体现的是 模板思想,其作用就类似于 “模板”,其目的是方便开发人员根据抽象类的格式来修改和创建新类
通过继承抽象类,可以方便程序的扩展
定义
抽象类:
包含抽象方法的类,使用 abstract
修饰
抽象方法:
只有方法声明,但是没有方法体的方法,使用 abstract
修饰,具体实现延迟到子类
抽象方法只能是 public
或者 protected
,不能使用 private
修饰
抽象方法不能使用 static
和 final
进行修饰
//将类也定义为抽象的:abstract
public abstract class Animal {
private String name;
// 将 eat 方法定义为抽象类的:abstract
public abstract void eat();
...
}
抽象类的特点
-
修饰符:
必须使用abstract
关键字修饰
抽象类:修饰符 abstract class 类名 {}
抽象方法:修饰符 abstract 返回类型 方法名 ();
-
抽象类不能被实例化,只能创建子类对象,但是 抽象类可以有构造函数
-
抽象类子类的两个选择
重写父类的所有抽象方法
定义成抽象类
抽象类成员的特点
-
成员变量
可以有普通的成员变量,也可以有成员常量 (final
) -
成员方法
可以有普通方法,也可以有抽象方法;
抽象类不一定有抽象方法,但是有抽象方法的类(或者接口)一定是抽象类(或者接口) -
构造方法
向普通类一样有构造方法,并且可以重载
接口与抽象类
当一个类实现接口时,如果这个类是抽象类,只需要实现接口中的部分抽象方法即可,否则需要实现接口中的所有抽象方法
一个类在继承一个类的同时,还可以实现接口,但是 extends
关键字必须位于 implements
关键字之前
符合 is-a
关系的设计使用继承关系
符合 has-a
关系的设计使用实现关系
抽象类也可以实现接口
接口中只可以定义常量属性,但是抽象类既可以定义常量属性也可以定义非常量属性