用 final 关键字修饰类可禁止继承,php 5.3+ 编译期校验,extends 时直接报 fatal error;final 仅适用于 class 和 method,不可用于 interface 或 trait;final class 中的 final method 冗余;适用于值对象、工具类、框架核心类等不可变场景,但滥用会损害扩展性。

PHP里怎么让一个类不能被继承
用 final 关键字修饰类,就能禁止它被继承。这是 PHP 5.3+ 的原生语法支持,不是模拟或运行时检查,编译期就报错。
为什么加 final 后 extends 会直接报错
因为 PHP 解析器在加载类定义时就校验了 final 标识。一旦发现子类试图 extends 一个 final 类,立刻抛出 Fatal error: Class X may not inherit from final class (Y),不会进入运行阶段。
-
final是语言级限制,比手动抛异常更早、更彻底 - 不支持“部分禁止”——不能只禁某个子类,也不能条件性放开
- 接口(
interface)和 trait 不支持final,只有class和method可用
final class 和 final function 能混用吗
可以,但语义不同,且互不影响:
-
final class锁死整个继承链,子类连定义都不允许 -
final function只锁住某个方法不被重写,类本身仍可被继承 - 如果一个类已经是
final,再给它的方法加final没意义,PHP 不报错但冗余
示例:
final class Config { public final function load() { /* ... */ } } —— 这里 final 在方法上是多余的。
立即学习“PHP免费学习笔记(深入)”;
哪些场景下必须用 final 类
核心是“这个类的设计意图就是不可变、不可扩展”。常见于:
- 值对象(如
DateTimeImmutable),继承可能破坏不可变性 - 工具类(如
Str、Arr静态类),本就不该有子类逻辑 - 框架内部关键类(如 Laravel 的
Container),防止被意外覆盖导致行为失控 - 单元测试中伪造类(mock class),有时需
final防止被测试代码意外继承
注意:滥用 final 会降低扩展性,比如你写的 SDK 类一旦标 final,下游项目就无法通过继承做定制,得改用组合或装饰器模式替代。
真正难的不是加 final,而是判断这个类是否真的“永远不需要被继承”。很多团队过早锁定,后来为绕开它,反而写出更糟的 hack 代码。










