在PHP中,你有線性單親繼承。不幸的是,這意味着你不能插入一箇中間的代理類而不修改Zend類的源代碼。
如果有必要(比如說,你需要成爲兩個不同DO類的孩子),但是也有辦法僞造多重繼承。
使用,神奇的方法,比如,你可以創建一個多代理:
class MultiProxy
{
private $poxies;
public function __construct(array $arr)
{
$this->proxies = $arr;
}
public function __get($name)
{
foreach($this->proxies as $proxy)
{
if(property_exists($proxy, $name))
{
try
{
return $proxy->$name
}
catch(Exception e)
{
// swallow it.
}
}
}
trigger_error("$name not found on $this");
}
public function __set($name, $val)
{
foreach($this->proxies as $proxy)
{
if(property_exists($proxy, $name))
{
try
{
$proxy->$name = $val;
}
catch(Exception e)
{
// swallow it.
}
}
}
trigger_error("$name not found on $this");
}
public function __call($name, $args)
{
foreach($this->proxies as $proxy)
{
$proxy = array($proxy, $name);
if(is_callable($proxy))
{
try
{
call_user_func_array($proxy, $args);
}
catch(Exception e)
{
// swallow it.
}
}
}
trigger_error("$name not found on $this");
}
public function __toString()
{
$ret = "[" . get_class($this) . '::{';
foreach($this->proxies as $proxy)
{
$ret .= get_class($proxy) . ',';
}
return substr($ret, 0, -1) .'}]';
}
}
// use:
class Foo{ public $a = 'FOO'; }
class Bar{ public function doSomething(){ echo 'YAY!'; } }
class Baz{ public $a = 'BAZ'; public function doSomething(){ echo 'BAAAZ!'; } }
$foo = new Foo();
$bar = new Bar(); // drink!
$baz = new Baz();
$multi = new MultiProxy(array($foo, $bar, $baz));
$multi->a = 'MULTI!';
echo $multi->a == $foo->a? 1:0;
$multi->doSomething();// YAY!
「_Complex inheritance is evil._」?爲什麼? – Tadeck
@Tadeck封裝是面向對象的一大優勢。繼承破壞封裝。見http://en.wikipedia.org/wiki/Design_Patterns –
好源(四人幫,而不是維基百科)。謝謝。 – Tadeck