简体   繁体   English

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

[英]Check if constant was overridden in child class in constructor of parent class?

I have an abstract class which defines several constants. 我有一个定义几个常量的抽象类。 Most of these constants will not be overridden by any child classes, but one should be. 大多数这些常量都不会被任何子类覆盖,但应该是。 I define this one constant as null in my abstract class, and in the child class I assign it a value. 我在抽象类中将此常量定义为null,并在子类中为其指定值。 The constructor will be the same in all child classes as well, so I have added a check to see if the constant was assigned a value or not, and throw an exception if it was not defined by the child class. 构造函数在所有子类中也是相同的,所以我添加了一个检查以查看是否为常量赋值,如果未由子类定义则抛出异常。

Some simplified code to sketch my problem: 一些简化的代码来描绘我的问题:

Parent abstract class: 父抽象类:

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();
}

Child class: 儿童班:

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

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

However, when instantiating ChildClass, the exception "Please define TEST_CONSTANT!" 但是,在实例化ChildClass时,异常“请定义TEST_CONSTANT!” will be thrown, even though the constant was overridden. 即使常数被覆盖,也会被抛出。 I understand that I can simply make it a mandatory parameter in the constructor, and set a member variable that way (which is probably the more logical/practical solution). 我理解我可以简单地将它作为构造函数中的必需参数,并以这种方式设置成员变量(这可能是更符合逻辑/实际的解决方案)。

In my case, it might not make much sense to use a constant for this purpose, but I'd still like to understand why this does not work. 在我的情况下,为此目的使用常量可能没有多大意义,但我仍然想知道为什么这不起作用。 It should be possible to override constants in child classes. 应该可以覆盖子类中的常量。 Does this override simply not occur until after the constructor is called? 在调用构造函数之后,这种覆盖是否只会发生? Is my check incorrect? 我的支票不正确吗? Would be nice to understand the logic and sequence of events at play here. 很高兴理解这里发生的事件的逻辑和顺序。

You need to pass the argument to defined() as a string: 您需要将参数传递给defined()作为字符串:

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

Otherwise, you're testing for the existence of a global constant called null (not 'null' but an actual null, which is pretty meaningless).... if you're trying to identify whether a global constant called value is defined, then you might also want to consider static::TEST_CONSTANT instead, which will take the value of static::TEST_CONSTANT from the child class that you've instantiated ( 'value' ) and test to see if a global constant with the name value has been defined. 否则,你正在测试是否存在一个名为null的全局常量(不是'null'而是一个实际的null,这是毫无意义的)....如果你试图确定是否定义了一个名为value的全局常量,那么您可能还需要考虑static::TEST_CONSTANTstatic::TEST_CONSTANT从您已实例化的子类( 'value' )中获取static::TEST_CONSTANT 'value'并测试以查看名称value是否具有全局常量已定义。

You need to use late static building to access static child properties (and constants) from parent class: 您需要使用后期静态构建来从父类访问静态子属性(和常量):

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();
}

Saying that, overriding constants looks a bit unusual. 说,重写常量看起来有点不寻常。 I am curious about usecase why you need it at all. 我很好奇usecase为什么你需要它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM