1. 包
1.1 什么是包
- 包是用来分门别类的管理各种不同类的,类似于文件夹、建包利于程序的管理和维护。
- 建包的语法格式:package 公司域名倒写.技术名称。包名建议全部英文小写,且具备意义。
- 建包语句必须在第一行,一般IDEA工具会帮助创建。
1.2 导包
- 相同包下的类可以直接访问,不同包下的类必须导包,才可以使用!导包格式:import 包名.类名
- 假如一个类中需要用到不同类,而这两个类的名称是一样的,那么默认只能导入一个类,另一个类要带包名访问。
2. 权限修饰符
2.1 什么是权限修饰符
- 权限修饰符:是用来控制一个成员能够被访问的范围。
- 可以修饰成员变量,方法,构造器,内部类,不同权限修饰符修饰的成员能够被访问的范围将受到限制。
2.2 权限修饰符的分类和具体作用范围
- 有四种作用范围由小到大(private -> 缺省 -> protected -> public)
自己定义成员(方法,成员变量,构造器等)一般需要满足如下要求: - 成员变量一般私有。
- 方法一般公开。
- 如果该成员只希望本类访问,使用private修饰。
- 如果该成员只希望本类,同一个包下的其他类和子类访问,使用protected修饰。
3. final
3.1 final的作用
- final关键字是最终的意思,可以修饰(类、方法、变量)
- 修饰类:表明该类是最终类,不能被继承。
- 修饰方法:表明该方法是最终方法,不能被重写。
- 修饰变量:表明该变量第一次赋值后,不能再次被赋值(有且仅能被赋值一次)。
3.2 final修饰变量的注意
- final修饰的变量是基本类型:那么存储的数据值不能发生改变。
- final修饰的变量是引用类型:那么存储的地址值不能发生改变,但是地址指向的对象内容是可以发生变化的。
4. 常量
4.1 常量是什么
- 常量是使用了public static final修饰的成员变量,必须有初始化值,而且执行的过程中其值不能被改变。
- 常量的作用和好处:可以用于做系统的配置信息,方便程序的维护,同时也能提高可读性。
4.2 常量的执行原理
- 在编译阶段会进行“宏替换”,把使用常量的地方全部替换成真实的字面量。
- 这样做的好处是让使用常量的程序执行性能与直接使用字面量是一样的。
5 枚举
5.1 枚举的概述
- 枚举是Java中的一种特殊类型
- 枚举的作用:是为了做信息的标志和信息的分类
- 枚举类的格式:
5.2 枚举的特征
- 枚举类都是继承了枚举类型:java.lang.Enum
- 枚举都是最终类,不可以被继承
- 枚举类的构造器都是私有的,枚举对外不能创建对象
- 枚举类的第一行默认都是罗列枚举对象的名称的
- 枚举类相当于是多例模式
6. 抽象类
6.1 抽象类概述
- 在Java中abstract是抽象的意思,可以修饰类、成员方法
- abstract修饰类,这个类就是抽象类;修饰方法,这个方法就是抽象方法。
注意: - 抽象方法只有方法签名,不能声明方法体。
- 一个类中如果定义了抽象方法,这个类必须声明成抽象类,否则报错。
6.2 抽象类的使用场景
- 抽象类可以理解成不完整的设计图,一般作为父类,让子类来继承
- 当父类知道子类一定要完成某些行为,但是每个子类该行为的实现又不同,于是该父类就把该行为定义成抽象方法的形式,具体实现交给子类去完成。此时这个类就可以声明成抽象类。
6.3 抽象类的特征、注意事项小结
- 类有的成员(成员变量、方法、构造器)抽象类都具备
- 抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类
- 一个类继承了抽象类必须重写完抽象类的全部抽象方法,否则这个类也必须定义成抽象类
- 不能用abstract修饰变量、代码块、构造器。
- ==最重要的特征:==得到了抽象方法,失去了创建对象的能力(有得有失)
final和abstract是什么关系?
- 互斥关系
- abstract定义的抽象类作为模板让子类继承,final定义的类不能被继承。
- 抽象方法定义通用功能让子类重写,final定义的方法子类不能重写。
6.4 抽象类的应用知识:模板方法模式
6.4.1 什么时候使用模板方法模式
- 使用场景说明:当系统中出现同一个功能多处在开发,而该功能中大部分代码是一样的,只有其中部分可能不同的时候。提高了代码的复用性
6.4.2 模板方法实现步骤
- 把功能定义成一个所谓的模板方法,放在抽象类中,模板方法中只定义通用且能确定的代码。
- 模板方法中不能决定的功能定义成抽象方法让具体子类去实现。
模板方法建议使用final修饰,这样会更专业,为什么呢?
答:模板方法是给子类直接使用的,不是让子类重写的,一旦子类重写了模板方法,则模板方法就失效了,因此,加上final后可以防止子类重写模板方法,这样更安全,专业。
public abstract class Student {
/**
正式:声明了模板方法模式
*/
public final void write(){
System.out.println("\t\t\t\t《我的爸爸》");
System.out.println("你的爸爸是啥样,来说说:");
// 正文部分(每个子类都要写的,每个子类写的情况不一样)
// 因此,模板方法把正文部分定义成抽象方法,交给具体的子类来完成
System.out.println(writeMain());
System.out.println("我的爸爸简直太好了~~");
}
public abstract String writeMain();
}
public class StudentMiddle extends Student{
@Override
public String writeMain() {
return "我的爸爸也很牛,开车都不看红绿灯的";
}
}
7. 接口
7.1 接口的概述、特点
- 接口的格式如下:
/**
声明了一个接口:体现一种规范,规范一定是公开的。
*/
public interface InterfaceDemo {
// 目标:接口中的成分特点:JDK 8之前只能有抽象方法和常量
// 1、常量
// 注意:由于接口体现规范思想,规范默认都是公开的,所以代码层面,public abstract final可以省略不写
String SCHOOL_NAME = "黑马程序员";
// public static final String SCHOOL_NAME = "黑马程序员";
// 2、抽象方法
// 注意:由于接口体现规范思想,规范默认都是公开的,所以代码层面,public abstract可以省略不写
void run();
// public abstract void run();
void eat();
// public abstract void eat();
}
7.2 接口的基本使用:被实现
- 接口是用来被类实现(implements)的,实现接口的类称为实现类。实现类可以理解成所谓的子类。
- 从上面可以看出,接口可以被类单实现,也可以被类多实现。
- 一个类实现接口,必须重写完全部接口的全部抽象方法,否则这个类需要定义成抽象类。
7.3 接口与接口的关系:多继承
7.3.1 基本小结
- 类和类的关系:单继承
- 类和接口的关系:多实现
- 接口和接口的关系:多继承,一个接口可以同时继承多个接口。
7.3.2 接口多继承的作用
- 规范合并,整合多个接口为同一接口,便于子类实现。
/**
接口可以多继承:一个接口可以同时继承多个接口
*/
public interface SportMan extends Law, People{
void run();
void competition();
}
7.4 JDK8开始接口新增方法(了解即可)
第一种:默认方法
- 类似之前写的普通实例方法:必须用default修饰;
- 默认会public修饰。需要用接口的实现类的对象来调用。
第二种:静态方法
- 默认会public修饰,必须static修饰;
- 注意:接口的静态方法必须用本身的接口名来调用。
第三种:私有方法
- 就是私有的实例方法,必须使用private修饰,从JDK9才开始有的。
- 只能在本类(接口)中被其他的默认方法或者私有方法访问。