【问题标题】:Check if constant was overridden in child class in constructor of parent class?检查父类的构造函数中的子类中的常量是否被覆盖?
【发布时间】:2016-01-26 16:45:25
【问题描述】:

我有一个定义了几个常量的抽象类。这些常量中的大多数不会被任何子类覆盖,但一个应该被覆盖。 我在抽象类中将这个常量定义为 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!”将被抛出,即使常量被覆盖。我知道我可以简单地将它作为构造函数中的强制参数,并以这种方式设置一个成员变量(这可能是更合乎逻辑/实用的解决方案)。

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

【问题讨论】:

  • 也许您应该使用static::TEST_CONSTANT 而不是self::TEST_CONSTANT

标签: php oop overriding constants


【解决方案1】:

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

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

否则,您正在测试是否存在名为 null 的全局常量(不是“null”,而是实际的 null,这毫无意义)....如果您尝试确定是否存在名为 @ 的全局常量987654324@ 已定义,那么您可能还需要考虑 static::TEST_CONSTANT,它将从您已实例化的子类 ('value') 中获取 static::TEST_CONSTANT 的值并测试以查看是否具有名称value 已定义。

【讨论】:

  • 即使 TEST_CONSTANT 在父类中为空,它仍然被定义。条件永远不会评估为假。
  • 好点,也是我没有预料到的。显然在 stackoverflow.com/questions/6187234/… 中没有真正直接的检查
  • 即使 TEST_CONSTANT 在父级中设置为 null,您仍然可以使用 if (!defined('static::TEST_CONSTANT') || empty(static::TEST_CONSTANT)) { 进行检查
【解决方案2】:

您需要使用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();
}

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

【讨论】:

  • 你说的不寻常是对的。正如我在问题中提到的那样,我确信对于我的用例,最好将常量转换为成员变量并将其设置在构造函数中。我只是在重构过程中尝试了这种方法,并很快意识到这不是理想的方法。我只是想知道为什么它不起作用。
猜你喜欢
  • 2013-07-13
  • 2020-06-27
  • 2011-10-13
  • 1970-01-01
  • 1970-01-01
  • 2020-09-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多