检查父类的构造函数中的子类是否覆盖了常量?

时间:2016-01-26 16:45:26

标签: php oop override constants

我有一个定义几个常量的抽象类。大多数这些常量都不会被任何子类覆盖,但一个应该。 我在抽象类中将此常量定义为null,并在子类中为其指定值。所有子类中的构造函数也是相同的,因此我添加了一个检查以查看是否为该常量赋值,如果未由子类定义则抛出异常。

草拟我的问题的一些简化代码:

父抽象类:

abstract class ParentClass {
    const TEST_CONSTANT = null;

    public function __construct()
    {
        if (!defined(self::TEST_CONSTANT)) {
            throw new Exception("Please define TEST_CONSTANT!");
        }
    }

    abstract protected function someFunction();
}

儿童班:

class ChildClass extends ParentClass {
    const TEST_CONSTANT = "value";

    protected function someFunction()
    {
        //some functionality here
    }
}

但是,在实例化ChildClass时,异常"请定义TEST_CONSTANT!"即使常数被覆盖,也会被抛出。我理解我可以简单地将它作为构造函数中的必需参数,并以这种方式设置成员变量(这可能是更符合逻辑/实际的解决方案)。

就我而言,为此目的使用常量可能没什么意义,但我仍然想了解为什么这不起作用。 应该可以覆盖子类中的常量。在调用构造函数之后,这种覆盖是否只会发生?我的支票不正确吗?很高兴理解这里发生的事件的逻辑和顺序。

2 个答案:

答案 0 :(得分:2)

您需要将参数作为字符串传递给defined()

if (!defined('self::TEST_CONSTANT')) {

否则,你正在测试是否存在一个名为null的全局常量(不是' null'而是一个实际的null,这是非常无意义的)....如果你'尝试确定是否定义了名为value的全局常量,那么您可能还需要考虑使用static::TEST_CONSTANT,这将取代您所在的子类中static::TEST_CONSTANT的值。已实例化('value')并测试以查看是否已定义名为value的全局常量。

答案 1 :(得分:1)

您需要使用late static building从父类访问静态子属性(和常量):

abstract class ParentClass {
    const TEST_CONSTANT = null;

    public function __construct()
    {
        if (!defined(static::TEST_CONSTANT)) {
            throw new Exception("Please define TEST_CONSTANT!");
        }
    }

    abstract protected function someFunction();
}

说,覆盖常量看起来有点不寻常。我很好奇usecase为什么你需要它。