为什么不能在子类中用常量值覆盖父变量?(PHP)

But*_*kus 1 php oop inheritance

我首先有一堂课,其中$name设置为“鲍勃”。在儿童班中,我设置$name为“Karen”,但它不起作用。

在我的回声陈述中,第一个说“鲍勃”而不是“凯伦”。使用子类方法的第二个方法虽然有效。

为什么会出现这种行为?

class First {

    public $name;

    public function __construct() {

        $this->name = 'bob';
    }
}

class Third extends First {

    public $name = 'Karen';
    public function set_name ($name) {
        $this->name = $name;
    }
}

$instance_of_third = new Third;
$third_name = $instance_of_third->name;

echo "<br />We're looking for Karen: $third_name<br />";
// $third_name here is 'bob' from parent class

$instance_of_third->set_name("Karen");
$third_name = $instance_of_third->name;
// $third_name here is 'Karen' only after using set_name()
echo "<br />We're looking for Karen: $third_name<br />";
Run Code Online (Sandbox Code Playgroud)

编辑:我添加了 2 行显示输出的确切内容。

即使$name在子类中显式设置为“Karen”,它set_name()也会显示为“bob”,除非使用该函数对其进行更改。

Gor*_*don 5

因为您Third没有自己的构造函数,所以它将从First. 继承在超类型和子类型之间创建了一种行为关系。

因此,当您创建 的新实例时Third,该实例将具有$name'Karen' 属性,但随后将调用继承的构造函数。这将名称设置为 Bob。如果您不想在子类型中出现这种行为,则必须向 中添加一个空构造函数Third,例如

class Third extends First
{
    public function __construct()
    {
        // prevents parent First::__construct
    }
}
Run Code Online (Sandbox Code Playgroud)

演示

另一种方法是删除ctor(或至少不在其中设置$name)并将$name父级中的属性预设为Bob。那么你最初的想法会起作用,例如

class First
{
    public $name = 'Bob';
}

class Third extends First
{
    public $name = 'Karen';
}
Run Code Online (Sandbox Code Playgroud)

演示

请查看 PHP 手册中有关继承和可见性的章节: