为什么可以覆盖在父 class 中使用的特征中定义的 属性 的初始值?

Why can you override the initial value of a property defined in a trait that is used in a parent class?

PHP 文档说明了以下关于重写特征属性的内容:

If a trait defines a property then a class can not define a property with the same name unless it is compatible (same visibility and initial value), otherwise a fatal error is issued.

但是,当您在抽象 class 中使用特征时,您可以覆盖 class 中特征中定义的属性,扩展该抽象 class:

<?php

trait PropertyTrait
{
    public $prop = 'default';   
}

abstract class A
{
    use PropertyTrait;
}

class B extends A
{
    public $prop = 'overridden';

    public function write()
    {
        echo $this->prop;       
    }
}

$b = new B();

$b->write(); // outputs "overridden"

Live demo

上面的代码有效,但我在文档中找不到任何关于它的参考。这是预期的功能吗?

因为出于所有意图和目的 B 没有使用 PropertyTraitA 使用它来组成摘要 class.

B 看不到 A 正在使用的特征。如果您要在 B 上执行 class_uses,您将得到一个空数组。 Docs, and example.

由于 B 没有使用任何特征,class 可以自由覆盖任何继承的属性。

A 是抽象 class 这一事实与此无关。任何 class 扩展使用特征组成的 class 都会发生相同的行为。