PHP继承通过extends实现单继承,子类自动继承父类public和protected属性与方法,private成员不可访问;构造函数需显式调用parent::__construct(),PHP 8.0起类型校验更严格,protected属性非“子类专属public”,应优先封装为protected方法。

PHP 8.0 中,子类继承父类属性时的默认访问行为没有发生根本性改变,但对访问控制和类型安全的校验更严格。核心规则仍是:子类自动继承父类的 public 和 protected 属性(含其值与可见性),而 private 属性完全不可见、不可访问、不可继承。
哪些属性能被子类直接使用
子类实例中可通过 $this->propertyName 直接读写以下两类属性:
-
public 属性:在父类中声明为
public $name;,子类可自由读写,外部也可访问 -
protected 属性:在父类中声明为
protected $config;,子类内部可读写,但外部不可访问
注意:private $token; 这类属性仅属于父类作用域,子类中写 $this->token 会静默创建一个同名新属性,而非访问父类的 —— 这是常见陷阱,不是继承,而是覆盖。
构造函数必须显式调用 parent::__construct()
PHP 8.0 不再隐式执行父类构造逻辑。若父类构造函数初始化了 protected 属性(如数据库连接、配置数组),子类构造函数中必须手动调用:
PHP 8.5.12 RC 1 候选版修复 BZ2、DOM、PDO、Opcache/JIT 和扩展内存安全问题,改进 Unicode 字素处理、URL 解析、TLS 流状态、信号分发及会话错误处理。
立即学习“PHP免费学习笔记(深入)”;
-
parent::__construct($args);—— 否则那些 protected 属性保持未初始化状态(null或默认值) - 不调用不会报错,但运行时可能因空值引发 Notice 或逻辑异常
- PHP 8.0+ 对参数类型、返回类型兼容性检查更严,若父类构造方法有类型声明,子类传参不匹配会触发
TypeError
protected 属性不是“子类专属 public”
很多开发者误以为 protected 是给子类开的“后门”,可以随意修改。实际上它只是语法许可,不提供语义保障:
- 子类可直接赋值
$this->cache = [];,但可能破坏父类预设的状态约束 - 多层继承(A → B → C)中,B 类修改了
protected $options,C 类行为可能意外变化,且无提示 - 单元测试若直接断言
$obj->options,一旦父类将该属性改为私有+getter,测试立即失败
更健壮的做法是:把需子类干预的逻辑封装成 protected 方法(如 protected function initDefaults(): array),而非暴露原始属性。
静态属性与 late static binding 的影响
PHP 8.0 继续支持 static:: 实现后期静态绑定。这对继承属性的静态访问很关键:
-
self::$data总指向定义该代码的类(哪怕在子类中调用) -
static::$data指向实际运行时的类,适合构建可继承的静态缓存或配置 - 若父类声明
protected static $version = '1.0';,子类可覆写为protected static $version = '2.0';,且static::$version会正确返回子类值


















