我正在尝试以最有效的方式解决设计难题,但我倾向于认为我真的需要一个多重继承。所以,我在这里,问专业人士。我正在创建一个活动记录库,它将使用不同的name
和value
变量执行几乎相同的操作。我在PHP 5.2.13
假设我有这些课程:
class Property {
protected $_props = array();
function set($name, $value) {
$this->_props[$name] = $value;
};
}
class ColorProperties extends Property {
function red($value) {
$this->set('red', $value);
}
function blue($value) {
$this->set('blue', $value);
}
}
class LayoutProperties extends Property {
function x($value) {
$this->set('x', $value);
}
function y($value) {
$this->set('y', $value);
}
}
现在我需要创建一个将继承ShapeProperties
和ColorProperties
的类LayoutProperties
。那样:
$shape = new ShapeProperties();
$shape->x(10);
$shape->red(255);
我之所以需要这样,就是在IDE中自动完成,每个属性都有大量的PHPDoc注释块。所以,似乎我倾向于绝望地复制/粘贴。
我有这些课程(块):
class Red {
function red();
}
class LightRed {
function light_red();
}
class Blue {
function blue();
}
class LightBlue {
function light_blue();
}
class Green {
function green();
}
class LightGreen {
function light_green();
}
现在我需要使用这些块构建大量的类,即:
class RGB extends Red, Green, Blue {
function red();
function blue();
function green();
}
class RLRB extends Red, LightRed, Blue {
function red();
function light_red();
function blue();
}
因此,如果我用接口切换word类,我将得到我需要的东西,但我需要工作实现而不需要加载样板代码。有没有办法/方法在PHP中解决这个问题?
答案 0 :(得分:2)
你可以使用魔术函数和委托来做类似的事情。我希望你的真实情况不是关于颜色,因为避免几行功能会有点过分。
您可以提供任意的实现列表并循环使用它们,直到找到具有相应方法名称的实现。用所有参数调用它。可能存在方法冲突,就像多重继承一样,除了在这里,没有编译器会告诉你。你也失去了参数验证等。
class Color
{
private $implementations;
function __construct($implementations)
{
$this->implementations = $implementations;
}
function __call($functionName, $args)
{
foreach ($this->implementations as $impl) {
$callback = array($impl, $functionName);
if (is_callable($callback)) {
return call_user_func_array($callback, $args);
}
}
throw new Exception("Method not found: $functionName");
}
}
class RGB
{
function __construct()
{
parent::__construct(array(
new Red,
new Green,
new Blue,
));
}
}
$color = new RGB;
$color->red();
答案 1 :(得分:1)
在不久的将来,可以使用php 5.4新功能 - traits
。这将是这样的:
trait RED{
function red(){ };
}
trait BLUE{
function blue(){ };
}
trait GREEN{
function green(){ };
}
class RGB{
use RED,GREEN,BLUE;
}
但是现在,最好的方法似乎是使用静态方法和依赖注入,如下所示:
class RED{
static function get_red($obj){
return '0x'.dechex($obj->red);
}
}
class RGB{
public $red;
public $green;
public $blue;
public function __construct($r,$g,$b){
$this->red = $r;
$this->green = $g;
$this->blue = $b;
}
public function get_red(){
return RED::get_red($this);
}
}
$rgb = new RGB(255,255,255);
echo $rgb->get_red();
但你仍然需要声明所有函数并使其从其他类调用方法。