Java 抽象类 相关知识点

Java 抽象类 相关知识点 1. 抽象类的定义与语法· 使用关键字 abstract 修饰的类称为抽象类。· 可以包含抽象方法使用 abstract 修饰没有方法体和具体方法有方法体。· 语法示例javapublic abstract class Animal {protected String name;public Animal(String name) {this.name name;}// 抽象方法public abstract void makeSound();// 具体方法public void sleep() {System.out.println(name is sleeping);}}2. 抽象类的核心特点· 不能实例化不能通过 new 关键字创建抽象类的对象只能通过子类实例化。· 可以包含构造器虽然不能实例化但可以有构造器用于给子类构造器调用初始化父类成员。· 可以包含成员变量与普通类一样可以定义各种访问权限的成员变量。· 可以包含具体方法既可以有抽象方法也可以有已实现的方法。· 可以包含 main 方法抽象类中也可以定义 main 方法可以运行但通常不这么做。· 可以继承其他类或实现接口抽象类可以继承一个普通类或另一个抽象类也可以实现多个接口。3. 抽象方法· 使用 abstract 修饰没有方法体以分号结束。· 必须被子类实现非抽象子类必须重写所有抽象方法抽象子类可以选择实现部分或全部抽象方法也可以继续声明抽象方法。· 抽象方法不能是 private、static、final、synchronized· private子类不可见无法重写。· static属于类级别不能被覆盖。· final禁止重写。· synchronized与方法体相关抽象方法无方法体无意义。4. 抽象类的继承· 当子类继承抽象类时· 如果子类是非抽象类则必须实现父类中所有的抽象方法。· 如果子类也是抽象类则可以选择实现部分抽象方法也可以完全不实现继续将未实现的方法作为抽象方法传递给下一级子类。· 子类可以重写父类的具体方法也可以添加新的抽象方法。5. 抽象类与普通类的区别特性 抽象类 普通类实例化 不能 new 可以 new抽象方法 可以包含0个或多个 不能包含继承 必须被继承才有意义 可以被继承也可不被继承构造器 可以有 可以有成员变量 可以有 可以有具体方法 可以有 可以有final 修饰 不能是 final否则无法继承 可以是 final6. 抽象类与接口的对比Java 8随着Java版本升级接口不断增强两者的界限变得模糊但仍有本质区别比较维度 抽象类 接口Interface关键字 abstract class interface继承/实现 单继承只能继承一个抽象类 多实现一个类可实现多个接口构造器 可以有 不能有接口没有构造器成员变量 可以是各种类型可以有非静态、非 final 变量 默认是 public static final 常量Java 9支持私有变量但仍是静态常量方法 可以有抽象方法、具体方法、静态方法 Java 8前只能有抽象方法Java 8可以有 default 和 static 方法Java 9可以有 private 方法访问修饰符 可以使用所有访问权限 默认 publicJava 9支持 private 方法设计思想 代码复用模板模式定义“是什么” 契约规范行为约定定义“能做什么”初始化顺序 先执行父类构造器再初始化子类成员 接口没有构造器不存在初始化顺序问题典型使用场景· 抽象类当多个类有公共代码需要复用且需要定义模板方法时例如模板方法模式。· 接口定义行为规范实现多态解耦例如各种回调接口、策略模式。7. 抽象类的设计意义与常见应用· 代码复用将子类共有的属性和方法提取到抽象类中避免重复代码。· 定义模板模板方法模式Template Method中抽象类定义算法的骨架具体方法将一些步骤延迟到子类实现抽象方法。javapublic abstract class Game {public final void play() { // 模板方法initialize();startPlay();endPlay();}abstract void initialize();abstract void startPlay();abstract void endPlay();}· 强制子类行为通过抽象方法强制子类提供特定实现保证一定的规范性。· 作为中间层在框架设计中常用抽象类作为基础类提供默认实现同时留出扩展点。8. 使用抽象类的注意事项· 抽象类可以没有抽象方法但即使没有抽象方法它仍然不能实例化常用于禁止直接实例化的工具类但这种情况更多用 final 类配合私有构造器。· 构造器的调用抽象类的构造器在子类实例化时被调用用于初始化父类成员。· 与 final 冲突抽象类不能同时被 final 修饰因为 final 类不可继承而抽象类必须被继承。· 访问权限抽象方法的访问权限不能是 private否则子类无法实现。· 异常抛出抽象方法可以声明抛出异常子类实现时抛出的异常必须是父类异常的子集或相同。9. 常见面试题· 抽象类和接口如何选择需要代码复用、定义共同状态成员变量时用抽象类需要多实现、定义能力契约时用接口。· 抽象类中能否有 main 方法可以抽象类可以包含 main 方法可以运行但实例化仍需通过子类。· 为什么抽象类不能实例化因为抽象类可能包含未实现的抽象方法如果允许实例化调用抽象方法会导致无法执行。· 抽象方法是否可以定义在非抽象类中不可以只有抽象类才能包含抽象方法。· 一个类继承抽象类但没有实现所有抽象方法怎么办该类必须声明为抽象类。