抽象方法必须定义在abstract类中且无方法体,所在类须用abstract声明;抽象类不可实例化但可作引用类型;子类须实现全部抽象方法或自身声明为abstract;abstract方法不能是private、static或final。

抽象方法必须定义在 abstract class 中,且不能有方法体(连大括号都不能写),否则编译直接报错。
抽象方法的声明语法必须严格满足
Java 要求抽象方法用 abstract 修饰符,且不能带方法实现(即不能有 {}),同时所在类必须用 abstract 声明。常见错误包括:
- 在普通类里写
abstract void run();→ 编译错误:Illegal modifier for the method; only public, protected, private, static, final, synchronized, native, strictfp are permitted - 在抽象类中写
abstract void walk() { }→ 编译错误:abstract methods cannot have a body - 漏掉
public或protected访问修饰符(默认包访问权限允许,但不推荐)→ 子类可能因包不同而无法重写
abstract class Animal {
// ✅ 正确:无方法体,访问修饰符明确
public abstract void makeSound();
// ❌ 错误:abstract 方法不能有 {}
// public abstract void sleep() {}
// ⚠️ 可行但受限:默认包访问,跨包子类无法继承
// abstract void move();
}
抽象类不能被实例化,但可声明引用变量
抽象类本质是“不完整的类型”,JVM 禁止调用 new Animal()。但它可以作为变量类型,指向具体子类实例——这是多态的关键基础。
-
Animal a = new Dog();合法,a.makeSound()运行时调用Dog的实现 -
new Animal();编译失败:Animal is abstract; cannot be instantiated - 抽象类可以有构造方法(供子类
super()调用),但不能是private(否则子类无法访问)
abstract class Vehicle {
protected String brand;
Vehicle(String brand) { this.brand = brand; } // ✅ 允许非-private 构造器
}
class Car extends Vehicle {
Car(String brand) { super(brand); } // 必须显式或隐式调用父类构造器
}
子类继承抽象类时,必须实现所有抽象方法,除非子类也声明为 abstract
这是编译器强制检查的规则。一旦子类不是抽象类,它就必须为父类中每个未实现的抽象方法提供具体版本,否则编译失败。
立即学习“Java免费学习笔记(深入)”;
- 若子类只实现部分抽象方法 → 编译错误:
The type X must implement the inherited abstract method Y - 若子类也加了
abstract修饰符,则可选择性实现(甚至一个都不实现) - 注意:重写时方法签名(名称、参数、返回类型)必须与父类一致;协变返回类型允许(如父类返回
Animal,子类可返回Dog)
abstract class Shape {
public abstract double area();
public abstract void draw();
}
// ✅ 全部实现
class Circle extends Shape {
public double area() { return 3.14; }
public void draw() { System.out.println("Circle drawn"); }
}
// ✅ 不实现,但自身抽象
abstract class Polygon extends Shape {
public void draw() { System.out.println("Polygon drawn"); }
// area() 没实现,合法,因为 Polygon 是 abstract
}
最容易被忽略的是:抽象方法不能是 private、static 或 final——这些修饰符与“强制子类覆盖”的语义冲突。编译器会立刻拒绝这类组合,比如 private abstract void foo(); 直接报错。










