Java 抽象类 知识点

  1. 定义与语法细节

· 抽象类:使用 abstract class 定义,如 public abstract class Animal { }

· 抽象方法:使用 abstract 修饰,没有方法体(直接以分号结尾)。

public abstract void makeSound();

· 类中可包含:

· 抽象方法(强制子类实现)

· 非抽象方法(有具体实现)

· 成员变量(可以是 private、protected、public、static、final 等)

· 构造方法(虽然不能实例化,但供子类调用)

· 静态代码块、实例代码块


  1. 继承与实现规则

· 子类通过 extends 继承抽象类。

· 必须实现所有抽象方法,否则子类也必须声明为 abstract。

· 子类可以重写父类的非抽象方法(普通方法也可以被重写)。

· 一个子类只能继承一个抽象类(单继承)。

· 抽象类可以实现接口(使用 implements),且可以不实现接口中的方法(交由具体子类实现)。


  1. 构造方法与初始化

· 抽象类有构造方法,但不能直接 new。

· 子类构造方法中必须通过 super(...) 调用父类构造方法(隐式或显式)。

· 初始化顺序:父类静态块 → 子类静态块 → 父类实例块 → 父类构造方法 → 子类实例块 → 子类构造方法。


  1. 关键限制(与修饰符的互斥)

修饰符组合 是否允许 原因

abstract + final ❌ 方法/类均不行 final 禁止重写/继承,与抽象矛盾

abstract + private ❌ 方法 private 不能被子类访问,无法重写

abstract + static ❌ 方法 静态方法属于类,不能重写

abstract + native ❌ 方法 native 已有实现(非Java),与抽象冲突


  1. 与接口的细致对比(补充要点)

· 字段:接口字段默认 public static final;抽象类无此限制。

· 方法可见性:抽象类可以有 protected、private 方法;接口方法(Java 8前)只能是 public。

· 状态:抽象类可以维护可变状态(非 final 字段);接口通常无状态(除非定义 static final 常量)。

· Java 8+ 接口新特性:default 和 static 方法,但依然不能有实例字段。

· 选择原则:需要共享代码、状态 → 抽象类;定义能力(多实现) → 接口。


  1. 典型应用模式

· 模板方法模式

抽象类中定义骨架方法(final 防止篡改),调用一系列抽象方法或钩子方法。

```java

public abstract class DataParser {

public final void parse() {

readData();

processData();

writeData();

}

protected abstract void readData();

protected abstract void processData();

protected void writeData() { } // 钩子,默认空实现

}

```

· 工厂方法模式:抽象类定义创建对象的抽象方法,子类具体实现。


  1. 常见误区与面试题

· 误区:抽象类不能有构造方法 ❌ (实际可以有,用于初始化父类字段)

· 误区:抽象方法不能有主体,但可以有 {} ❌ (必须 ; 结尾,不能有大括号)

· 误区:abstract 类中只能有抽象方法 ❌ (可以有具体方法)

· 面试题:为什么抽象类可以 main 方法?

答:main 是静态方法,与实例化无关,可以正常执行,但需要子类或间接调用。

· 面试题:abstract 类能否实现接口且不实现方法?

答:可以,作为抽象类,它可以把接口方法继续声明为抽象方法,留给子类实现。


  1. 代码示例(完整演示)

```java

public abstract class Vehicle {

protected String brand;

public Vehicle(String brand) {

this.brand = brand;

}

public abstract void start(); // 抽象方法

public void showBrand() { // 具体方法

System.out.println("Brand: " + brand);

}

}

public class Car extends Vehicle {

public Car(String brand) {

super(brand);

}

@Override

public void start() {

System.out.println(brand + " car starts with key.");

}

}

// 使用

Vehicle v = new Car("Toyota");

v.start(); // Toyota car starts with key.

v.showBrand(); // Brand: Toyota

```

相关推荐
小羊没烦恼!2 天前
微服务化的基石——持续集成
java·大数据·word·powerpoint·.net
倒头就睡的小比特2 天前
算法竞赛C++常用的STL
c++·算法
俊昭喜喜里2 天前
java中的继承和多态的区别
java
小羊没烦恼!2 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
譕痕2 天前
JSONObject与JSONArray封装数据格式区别
java·json
胡写代码2 天前
别再前后端各写一套表单校验了
java·后端
小鱼能吃糖2 天前
缺陷修复总览 · mall电商项目:5类缺陷,1个病根,4个业务域
java·电商
此时不提桶,更待何时2 天前
01-06-A-JVM排查实战详解
java·jvm
伞伞悦读2 天前
【第38期】Python 模块与包详解:import、from、模块搜索路径、包结构和 __init__
开发语言·python
猎头南楼2 天前
知识社区推荐系统实践:新用户冷启动与长短期兴趣建模的挑战 资深推荐算法工程师
人工智能·深度学习·算法·机器学习