Во-первых, я действительно не думаю, что вы достаточно хорошо понимаете объектно-ориентированные принципы, чтобы запрашивать эту функциональность.Это действительно не нужно со стилем ООП, который реализует PHP.
Вы запрашиваете что-то вроде условных дополнений.Это возможно реализовать, но это огромный клочок, и его следует избегать.Вот что-то, что я собрал некоторое время назад, когда тестировал некоторые концепции:
<?php
class Mixin
{
private $objects = array();
private $funcs = array();
public function addMixin(Mixable $object)
{
$exported_vars = $object->exportVars();
foreach ($exported_vars as $key => &$ref)
$this->$key = &$ref;
$vars = array();
foreach (array_keys(get_object_vars($this)) as $key)
$vars[$key] = &$this->$key;
$object->importVars($vars);
$this->objects[] = $object;
}
public function __call($method, $args)
{
if (!isset($this->funcs[$method]))
{
$found = false;
foreach ($this->objects as $obj)
{
if (method_exists($obj, $method))
{
$found = true;
$this->funcs[$method] = array($obj, $method);
break;
}
}
if (!$found)
throw new Exception("method doesn't exist");
}
return call_user_func_array($this->funcs[$method], $args);
}
}
class Mixable
{
public function exportVars()
{
$vars = array();
foreach (array_keys(get_object_vars($this)) as $key)
{
$vars[$key] = &$this->$key;
}
return $vars;
}
public function importVars($vars)
{
foreach ($vars as $key => &$ref)
{
$this->$key = &$ref;
}
}
}
?>
Вы бы использовали это как:
<?php
class Parent1 extends Mixable
{
protected $name = 'Parent 1';
public function p1()
{
print "P1\n";
}
}
class Parent2 extends Mixable
{
protected $name = 'Parent 2';
public function p2()
{
print "P2\n";
}
}
class Child1 extends Mixin
{
public function whoAmI()
{
print $this->name."\n";
}
}
$foo = new Child1();
if (mt_rand(1, 2) == 1)
{
$foo->addMixin(new Parent1());
$foo->p1();
}
else
{
$foo->addMixin(new Parent2());
$foo->p2();
}
$foo->whoAmI();
?>
Пожалуйста, не пытайтесь использовать код!Даже если бы он был готов к производству, это ужасная концепция.Я поставил его здесь, чтобы показать вам, как это будет работать.
Я думаю, что вы действительно должны делать что-то более похожее на шаблон Factory: создайте класс CarFactory
, который возвращает правильнов подклассе Car
.(Или вы можете создать фабричный метод в классе Car
.)
Это может быть что-то вроде Car::get($_POST['brand'])
.