PHP - 强制类声明属性

php
2022-08-30 22:21:49

我有一组扩展抽象类的类。抽象类包含利用后期静态绑定来获取子类中定义的信息的方法。例如,抽象类可能有一个包含以下行的方法:

$var = static::$childVar . ' some text';

这样,抽象类中定义的方法可以在运行时基于子类中定义的变量的值生成不同的字符串。

我想做的是有一些机制来强制子类声明这个变量,从而消除了在未设置变量时调用方法的可能性。

使用接口,可以要求类来定义方法(和常量,不幸的是,这些方法不能使用公共/受保护/私有来修改其可见性)。因此,如果一个类实现了一个接口,但没有定义接口中指定的所有方法,则会生成一个错误。但是,没有办法使用接口来要求类来定义属性。

我已经看到一些材料建议在界面中使用getter方法(例如getChildVar())隐式要求变量声明,但这不适合我,因为我不希望变量在类之外访问(它们具有可见性)。protected

同样,常量也不起作用,因为它们不支持可见性修饰符。protected

我知道我总是可以使用一个语句来检查抽象类的方法(甚至在构造函数中),但与使用接口来确保定义方法相比,这似乎不优雅。我想知道是否有一些标准的方法可以做到这一点,而无需在我的抽象类中对要求进行硬编码。isset()

顺便说一句,如果有人知道为什么你不能在接口内声明变量,我很想知道推理是什么。对我来说,这似乎是一个重大的疏忽。

任何帮助将不胜感激。


答案 1

不能在接口中强制实施变量,因为接口是如何使用类的公共表示形式。如果我是另一个加入你的项目的开发人员,我希望能够查看接口,并知道我可以假设的所有方法都是在实现该接口的类中实现的。这与私有或受保护的财产无关,或者实际上与任何特定财产有关。Getters/setters是这类事情的标准。

现在的疏忽是,你不能有一个神奇的方法来尝试访问一个未定义的静态属性。这将是您在这里的理想解决方案。

如果在运行时声明静态属性,为什么不强制执行一个方法,或者放置一个父类方法,该方法获取后期静态绑定属性并在未设置时引发错误?您甚至可以实现“驱动程序”模式来实现此目的:setChildVar()

<?php

class MyParentClass {

    public function __get($key)
    {
        if ( !isset(static::$$key))
        {
            throw new Exception('Child class '.get_called_class().' failed to define static '.$key.' property');
        }

        return static::$$key;
    }

    public function getText()
    {
        return $this->childVar . ' some text';
    }

}

class MyChildClass extends MyParentClass {

    protected static $childVar = 'some value:';

}

$a = new MyChildClass;
echo $a->getText(); // some value: some text

答案 2

推荐