重写类常量与属性

2022-08-30 07:14:54

我想更好地理解为什么在下面的场景中,类常量与实例变量的继承方式存在差异。

<?php
class ParentClass {
    const TEST = "ONE";
    protected $test = "ONE";

    public function showTest(){
        echo self::TEST;
        echo $this->test;
    }
}

class ChildClass extends ParentClass {
    const TEST = "TWO";
    protected $test = "TWO";

    public function myTest(){
        echo self::TEST;
        echo $this->test;
    }
}

$child = new ChildClass();
$child->myTest();
$child->showTest();

输出:

TWO
TWO
ONE
TWO

在上面的代码中,ChildClass 没有 showTest() 方法,因此继承使用 ParentClass showTest() 方法。结果显示,由于该方法在 ParentClass 上执行,因此正在计算 Test 常量的 ParentClass 版本,而由于它通过继承在 ChildClass 上下文中进行计算,因此正在评估 ChildClass 成员变量$test。

我已经阅读了文档,但似乎看不到任何提及这种细微差别的内容。任何人都可以为我提供一些启示吗?


答案 1

self::不具有继承意识,并且始终引用正在执行它的类。如果您使用的是 php5.3+,则可以尝试使用继承感知功能。static::TESTstatic::

不同之处在于使用“后期静态绑定”。在此处查找更多信息:static::

http://php.net/manual/en/language.oop5.late-static-bindings.php

这是我写的一个简单的测试脚本:

<?php

class One
{
    const TEST = "test1";

    function test() { echo static::TEST; }
}
class Two extends One
{
    const TEST = "test2";
}

$c = new Two();

$c->test();

输出

test2

答案 2

在 PHP 中,self 是指在其中定义被调用方法或属性的类。因此,在你的情况下,你正在调用 ,所以它使用该类中的变量。然后使用 in ,这样它就会引用该类中的变量。selfChildClassselfParentClass

如果仍希望子类重写父类的 ,则将父类中的以下代码调整为:const

public function showTest(){
    echo static::TEST;
    echo $this->test;
}

记下关键字。这是使用“后期静态绑定”。现在你的父类将调用你的子类的 const。static


推荐