abstract方法必须被非abstract子类实现,否则编译报错;它只能存在于abstract类或interface中,不能在普通类中声明;子类若不实现则自身须声明为abstract,且实现时方法签名和访问权限须严格匹配。

是的,abstract 方法必须被非 abstract 的子类实现,否则编译直接报错。 这不是运行时约束,而是 Java 编译器强制执行的语法规则。
abstract 方法只能出现在 abstract 类或 interface 中
Java 不允许在普通(concrete)类里声明 abstract 方法。否则会触发编译错误:Illegal combination of modifiers: 'abstract' and 'final'(如果误加了 final),或更常见的:abstract methods cannot be in a non-abstract class。
-
abstract类可以包含abstract方法和具体方法,但自己不能被实例化 -
interface中所有方法默认是public abstract(Java 8+ 允许default和static方法,但它们不是 abstract) - 从 Java 9 开始,
private方法可在interface中定义,但它们不能是abstract
子类不实现 abstract 方法就只能也声明为 abstract
如果一个非 abstract 类继承了含 abstract 方法的父类(或实现了含 abstract 方法的 interface),它必须覆盖并实现所有未实现的 abstract 方法。否则编译失败,错误信息类似:ClassName is not abstract and does not override abstract method xxx() in YYY。
- 子类选择不实现?那它自己必须加上
abstract修饰符 - 实现时方法签名(名称、参数类型、返回类型协变规则、异常声明)必须严格匹配,访问权限不能比父类更严格(如父类是
protected,子类不能用private) - 接口中的
default方法不是abstract,不强制重写;但若子类想覆盖它,仍需用public(接口方法默认 public,不可降级)
常见误判场景:Lambda 和函数式接口
看到 Runnable r = () -> System.out.println("ok"); 就以为“没实现 abstract 方法”?其实不然——Lambda 是编译器对函数式接口(只有一个 abstract 方法的 interface)的语法糖,底层仍生成了实现了该方法的匿名类或 invokedynamic 调用点。
立即学习“Java免费学习笔记(深入)”;
- 函数式接口(如
Runnable、Comparator)本身有且仅有一个abstract方法,Lambda 只是简化写法,不改变“必须实现”的本质 - 如果接口意外添加第二个
abstract方法,它就不再是函数式接口,原有 Lambda 表达式会立即编译失败 -
@FunctionalInterface注解不是必需的,但加了之后,编译器会检查是否真只含一个abstract方法
interface Animal {
void makeSound(); // abstract method —— 必须被实现
default void sleep() { System.out.println("Zzz"); } // not abstract
}
class Dog implements Animal {
@Override
public void makeSound() { // ✅ 必须写,否则编译不过
System.out.println("Woof!");
}
}
// class Cat implements Animal {} // ❌ 编译错误:Cat is not abstract and does not override abstract method makeSound()
最容易被忽略的是:abstract 方法的实现不是“可选优化”,而是编译期铁律。哪怕你 100% 确定某个抽象方法永远不被调用(比如用于未来扩展),只要子类是非 abstract 的,就必须提供空实现或抛异常——否则连 javac 这关都过不去。









