abstract是面向对象编程中用于声明抽象类或抽象成员的修饰符,抽象类不能实例化,必须由子类继承并实现所有抽象方法;抽象方法仅定义签名、无实现,须用override重写,不可与static、final等共存。

抽象类不能直接创建对象,必须通过子类继承并实现所有抽象方法后才能使用。核心在于用 abstract 关键字标记类和方法,明确“模板”与“强制实现”的边界。
怎么声明一个抽象类
在类定义前加 abstract 修饰符,类名、大括号结构不变,但不能再用 new 实例化:
-
abstract class Animal { ... }是合法的抽象类声明 -
new Animal()编译直接报错:“Animal is abstract; cannot be instantiated” - 类中可以包含普通字段、构造器、具体方法(有实现)、抽象方法(无实现)
- 只要类里有一个 abstract 方法,这个类就必须声明为 abstract class
抽象方法怎么写、有什么限制
抽象方法只负责定义行为契约,不提供具体逻辑,语法上更严格:
- 必须用 abstract 修饰,且以分号结尾,不能带方法体(即没有
{}) - 不能是
private、static或final—— 因为它们与“强制子类重写”的设计目标冲突 - 示例:
public abstract void move();合法;private abstract void sleep();编译失败 - 子类若非 abstract,必须用
@Override提供完全匹配的方法签名(含返回类型、参数、访问权限不能更严格)
子类继承时的两种路径
继承抽象类不是为了“复用就完事”,而是选择走哪条实现路线:
- 走具体实现路线:子类是普通类,必须重写父类全部抽象方法,否则编译不通过
- 走继续抽象路线:子类自己也加 abstract,可选择性实现部分抽象方法,把剩余约束留给下一级子类
- 抽象类的构造器可以被子类调用(通过
super()),用于初始化共用状态,比如protected String name; - 抽象类里的具体方法(如
public void breathe() { ... })可直接被子类继承调用,无需重写
什么时候该用抽象类,而不是接口
抽象类适合表达“是什么”+“共享实现”的场景:
- 多个类有共同字段(如
id、createdAt)和基础逻辑(如validate()),但关键行为(如calculatePrice())因类型而异 - 需要构造器初始化、支持
protected成员、或想让子类天然拥有“is-a”关系(如Dogis anAnimal) - 接口更适合定义“能做什么”(
Runnable、Serializable),且支持一个类实现多个接口 - Java 8+ 接口虽可有 default/static 方法,但无法定义实例字段或构造逻辑,这是抽象类不可替代的地方










