PHP类继承必须写在class定义开头且仅支持单继承;子类继承public/protected成员但不可访问private;extends位置错误、多继承、父类未定义或命名空间路径不全均导致解析或致命错误;重写方法需注意parent::调用限制及构造函数显式调用;static::实现后期静态绑定而self::指向定义类;抽象类继承须extends在前implements在后,且子类须实现所有抽象方法。

PHP里用extends继承类,语法很简单但容易错位置
PHP类继承必须写在class定义的开头,且只能继承一个父类——不支持多继承。子类会自动获得父类的public和protected成员,但拿不到private的。
常见错误是把extends写在class声明中间,或者试图继承多个类(比如class A extends B, C),这会直接报Parse error: syntax error。
-
extends必须紧跟class 子类名之后,中间不能有空行或注释干扰 - 父类必须已定义(提前声明或已
require/include),否则触发Fatal error: Class 'XXX' not found - 如果父类在命名空间里,子类
extends时必须用完整限定名,比如extends \Vendor\Lib\ParentClass
子类重写父类方法时,parent::调用要小心作用域
重写__construct、__toString等魔术方法时,如果需要复用父类逻辑,得显式用parent::methodName()调用。但注意:parent::只访问父类的public/protected方法,且不能绕过访问控制——比如父类方法是private,子类里写parent::xxx()会报Fatal error: Cannot access private method。
- 构造函数重写后,如果不手动调
parent::__construct(),父类初始化逻辑就完全丢失 -
parent::不能用于静态上下文调用非静态方法(反之亦然),否则报Strict Standards或Fatal error - PHP 8.0+ 对
parent::调用做了更严格检查,比如父类方法签名变了,子类没同步更新类型声明,可能触发TypeError
继承链中static::和self::行为差异明显
子类里用self::始终指向定义该代码的类,而static::遵循“后期静态绑定”(Late Static Binding),指向实际调用时的类。这个区别在工厂方法、单例或静态属性操作里特别关键。
立即学习“PHP免费学习笔记(深入)”;
比如父类有个static $instance和self::getInstance(),子类调用时拿到的是父类的$instance;换成static::getInstance(),才真正隔离子类实例。
- 用
self::读取静态属性时,永远读的是当前类(哪怕在子类里调用) -
static::能正确解析new static(),实现真正的“返回当前类实例”,而new self()永远返回定义处的类 - PHP 5.3+ 才支持
static::,老项目升级时要注意兼容性
接口和抽象类混用时,extends和implements顺序不能颠倒
一个类既要继承抽象类,又要实现接口,PHP强制要求extends在前、implements在后。写成class Child implements I1, I2 extends Parent会直接语法报错。
另外,抽象类里的抽象方法,子类必须全部实现(除非子类也声明为abstract);而接口方法即使子类没实现,只要父类实现了,也算满足契约——这点容易被忽略。
- 正确写法:
class Child extends AbstractParent implements InterfaceA, InterfaceB - 如果父类是抽象类且含抽象方法,子类必须覆盖所有抽象方法,否则报
Fatal error: Class Child contains 1 abstract method - 接口方法可以由父类实现,子类无需重复写,但别误以为“没写就是没实现”——得看整个继承链
继承不是套娃游戏,关键是搞清访问控制、静态绑定和初始化时机这三个地方。多数问题其实都出在没想清楚“这个parent::到底找谁”或者“static::此刻指向哪一层”。











