class Multi
{
public $_Exemplars_=array();
public $_Classes_=array();
public $_Dynamic_=array();
public $_Child_=null;
////
////
protected function __construct()
{
foreach ($this->_Classes_ as $Class=>$Args)
{
switch ( count($Args) )
{
case 0:
$this->_Exemplars_[$Class]=new $Class;
break;
case 1:
$this->_Exemplars_[$Class]=new $Class($Args[0]);
break;
case 2:
$this->_Exemplars_[$Class]=new $Class($Args[0], $Args[1]);
break;
case 3:
$this->_Exemplars_[$Class]=new $Class($Args[0], $Args[1], $Args[2]);
break;
case 4:
$this->_Exemplars_[$Class]=new $Class($Args[0], $Args[1], $Args[2], $Args[3]);
break;
case 5:
$this->_Exemplars_[$Class]=new $Class($Args[0], $Args[1], $Args[2], $Args[3], $Args[4]);
break;
}
////
$this->_Exemplars_[$Class]->_Child_=$this;
}
}
////
////
public function __get($_Key)
{
static $Searched;
////
if ( isset($this->_Exemplars_[$_Key]) )
{
$Searched=false;
////
return $this->_Exemplars_[$_Key];
}
////
if ( isset($this->_Dynamic_[$_Key]) )
{
$Searched=false;
////
return $this->_Dynamic_[$_Key];
}
////
if ( ($this->_Child_!=null) && !$Searched )
{
return $this->_Child_->$_Key;
}
////
$Searched=true;
////
$Count=count($this->_Exemplars_);
$Exemplar=end($this->_Exemplars_);
for ($i=$Count-1; $i>=0; $i--)
{
if ( isset($Exemplar->$_Key) )
{
$Searched=false;
////
return $Exemplar->$_Key;
}
////
$Result=$Exemplar->$_Key;
////
if ( !$Searched ) return $Result;
////
$Exemplar=prev($this->_Exemplars_);
}
////
return;
}
////
////
public function __set($_Key, $_Value)
{
static $Searched;
////
if ( isset($this->_Dynamic_[$_Key]) )
{
$Searched=false;
////
$this->_Dynamic_[$_Key]=$_Value;
////
return;
}
if ( ($this->_Child_!=null) && !$Searched )
{
$this->_Child_->$_Key=$_Value;
////
return;
}
////
$Searched=true;
////
$Count=count($this->_Exemplars_);
$Exemplar=end($this->_Exemplars_);
for ($i=$Count-1; $i>=0; $i--)
{
if ( isset($Exemplar->$_Key) )
{
$Searched=false;
////
$Exemplar->$_Key=$_Value;
////
return;
}
////
$Exemplar->$_Key=$_Value;
////
if ( !$Searched ) return;
////
$Exemplar=prev($this->_Exemplars_);
}
}
////
////
public function __call($_Method, $_Args)
{
static $Searched;
////
if ( ($this->_Child_!=null) && !$Searched )
{
return call_user_func_array(array($this->_Child_, $_Method), $_Args);
}
////
$Searched=true;
////
$Count=count($this->_Exemplars_);
$Exemplar=end($this->_Exemplars_);
for ($i=$Count-1; $i>=0; $i--)
{
if ( method_exists($Exemplar, $_Method) )
{
$Searched=false;
////
return call_user_func_array(array($Exemplar, $_Method), $_Args);
}
////
$Result=call_user_func_array(array($Exemplar, $_Method), $_Args);
////
if ( !$Searched ) return $Result;
////
$Exemplar=prev($this->_Exemplars_);
}
////
return;
}
}
class A1 extends Multi
{
public function __construct()
{
Multi::__construct();
}
////
////
public function TestA1_1()
{
print("A1_1<br>");
}
////
////
public function TestA1_2()
{
print($this->TestA2_2());
}
}
class A2 extends Multi
{
public function __construct()
{
Multi::__construct();
}
////
////
public function TestA2_2()
{
print("A2_2<br>");
}
}
class A3 extends Multi
{
public function __construct()
{
Multi::__construct();
}
}
class B1 extends Multi
{
public function __construct()
{
$this->_Classes_=array(
"A1"=>array(),
"A2"=>array(),
"A3"=>array()
);
////
Multi::__construct();
}
}
$B1=new B1;
$B1->TestA1_1();
$B1->TestA1_2();
$this->A->B->C->_Child_=null;
$this->A->B->C->ParentMethod();
$this->A->B->C->_Child_=$this->A->B;
class Multi
{
public $_Instances_ = array();
public $_Child_ = null;
protected function __construct( $classes=NULL ) {
if (! $classes)
return;
foreach( $classes as $class=>$args ) {
if( is_string($args) ) { # нет параметров, только имя класса
$this->_Instances_[$args] = new $args();
$this->_Instances_[$args]->_Child_ = $this;
} else {
foreach( $args as &$arg )
$arg = var_export($arg, TRUE);
eval( '$this->_Instances_["'.$class.'"] = new '.$class.'('.implode(',', $args).');' );
$this->_Instances_[$class]->_Child_ = $this;
}
}
}
public function __get( $k )
{
$child = $this;
while( $child->_Child_ )
$child = $this->_Child_;
if (! $child)
$child = $this;
return $this->_find( $k );
}
protected function _find( $k ) {
foreach( $this->_Instances_ as $inst ) {
$r = $inst->_find( $k );
if( isset($r) )
return $r;
}
if( isset($this->$k) )
return $this->$k;
}
public function get( $k, $scope='' ) {
$classes = explode( '::', $scope );
$o = $this;
foreach( $classes as $class )
if( $o->_Instances_[ $class ] )
$o = $o->_Instances_[ $class ];
else
return;
return $o->_find( $k );
}
}
class A1 extends Multi
{
public $a = 1;
public function __construct()
{
Multi::__construct();
}
}
class A2 extends Multi
{
public $a = 2;
public function __construct()
{
Multi::__construct();
}
}
class B1 extends Multi
{
public function __construct()
{
Multi::__construct(array( 'A1', 'A2' => array('A2_arg') ));
}
}
$B1=new B1;
var_dump($B1->a);
var_dump($B1->get('a', 'A2'));
есть в этом что-то, а тебе множественное наследование зачем, а?В общих чертах - не нужно этого хотеть, если вы этого хотите значит у вас не правильная архитектура приложения.
ну я бы поспорил, да не будуeval нельзя использовать никогда, андестанд?

Как я уже писал по этому поводу, вызывается то свойство или метод, которые были определены позднее. По этому же принципу, кстати, строится аналогичная иерархия в Ява-Скрипте, естественно, встроенными средствами.если у тебя в объектах будет одно и тоже свойство или метод, из какого объекта брать/вызывать?
Речь идет об уменьшении количества информации, необходимой для запоминания разработчиком. Необходимость помнить не только названия метода/свойства, но еще и его класс, увеличивает это количество ровно в два раза. Более того, в процессе проектирования, не исключено перемещение того или иного метода/свойства в другой класс. И тогда нужно будет не только переучивать их локацию, но и менять код по всему проекту.Нда.. Тоесть к какому объекту относится свойство/метод запомнить трудно, а все свойства/методы помнить для всех объектов - нет.
Ширина Колеса, которая меня будет интересовать, совпадает с Шириной Резины, насколько я понимаю (я не автомобилист). Значит, Резина будет определяться последней. Если же я захочу узнать Ширину Диска, то сделаю это через метод Пэрент.Класс Диск и класс Резина это предки класса Колесо, тебе нужно достать ширину, у них она разная.
Оно тебе точно надо?