PHP任何组合/继承解决方案,以避免多重继承?

时间:2012-01-22 22:33:42

标签: php inheritance composition boilerplate

我正在尝试以最有效的方式解决设计难题,但我倾向于认为我真的需要一个多重继承。所以,我在这里,问专业人士。我正在创建一个活动记录库,它将使用不同的namevalue变量执行几乎相同的操作。我在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);
    }
}

现在我需要创建一个将继承ShapePropertiesColorProperties的类LayoutProperties。那样:

$shape = new ShapeProperties();
$shape->x(10);
$shape->red(255);

我之所以需要这样,就是在IDE中自动完成,每个属性都有大量的PHPDoc注释块。所以,似乎我倾向于绝望地复制/粘贴。

OLD BODY(编辑前)

我有这些课程(块):

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中解决这个问题?

2 个答案:

答案 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(); 

但你仍然需要声明所有函数并使其从其他类调用方法。