2012-01-17 140 views
11

我有一组扩展抽象类的类。抽象类包含使用后期静态绑定来获取子类中定义的信息的方法。因此,例如,抽象类可能具有包含线的方法:PHP - 强制类声明属性

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

以这种方式,能够在运行时在抽象类中定义的方法,以基于一个变量的值不同串在子类中定义。

我想要做的是有一些机制,迫使子类声明这个变量,消除如果变量没有设置被调用方法的可能性。

使用接口,可能需要一个类来定义方法(以及常量,不幸的是它们的可见性不能通过public/protected/private修改)。所以如果一个类实现了一个接口,但是没有定义接口中指定的所有方法,则会产生一个错误。但是,没有办法使用接口来要求类定义属性。

我已经看到一些建议在接口中使用getter方法的材料(例如getChildVar())隐式地要求变量声明,但这不适合我,因为我不想让变量在类之外访问(他们有protected知名度)。

类似地,常量不起作用,因为它们不支持protected可见性修改器。

我知道我总是可以使用isset()语句在抽象类的方法(或者甚至是构造函数)中检查它,但与使用接口确保方法定义相比,这看起来不够优雅。我想知道是否有一些标准的方法来做到这一点,而不用硬编码抽象类中的需求。顺便说一句,如果有人知道你为什么不能在接口中声明变量,那么我很想知道推理是什么。这对我来说似乎是一个重大的监督。

任何帮助将不胜感激。

回答

10

您无法在界面中强制实施变量,因为界面是关于如何使用您的课程的公开说明。如果我是另一位参与项目的开发人员,我希望能够看看界面,并且知道我可以假设的所有方法都是在类中实现的,并且实现了该界面。这与私人或受保护的财产不是完全相关的,或者对于这个问题确实有任何特定的财产。吸气剂/定型剂是这种事情的标准。

现在的监管权力是你不能有一个神奇的方法试图访问一个未定义的静态属性。这对你来说是理想的解决方案。

如果在运行时声明静态属性,为什么不执行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 
+0

感谢您的解释。我现在明白为什么接口不允许变量声明(尽管我不确定我完全同意该决定背后的原因)。我实际上想出了几乎与行相同的代码,因此很高兴知道我做得对。 – C106 2012-01-17 12:02:49