First off, I really don't think you understand object oriented principles well enough to ask for this functionality. It's not really needed with the style of OOP that PHP implements.
You are requesting something like conditional mix-ins. It's possible to implement it, but it is a huge kludge and should be avoided. Here's something I put together a while ago when I was just testing some concepts:
<?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;
}
}
}
?>
You would use it like:
<?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();
?>
Please do not try to use the code! Even if it were production ready, it's a terrible concept. I put it here to show you how it would work.
I think what you really should be doing is something more like a Factory pattern: build a CarFactory
class that returns a properly subclassed Car
. (Or you could create a factory method within a Car
class.)
It could be something like Car::get($_POST['brand'])
.