... passiamo a qualcosa di concreto ...
Codice PHP:
<?php
class TypeHintOverloadable {
public function __call($method, $arguments){
for(
$methods = call_user_func(array(new ReflectionObject($this), 'getMethods')),
$re = '/^'.$method.'[0-9]+$/',
$i = 0, $j = count($methods), $k = count($arguments);
$i < $j; $i++
) {
if(
preg_match($re, $methods[$i]->name) &&
$methods[$i]->getNumberOfRequiredParameters() === $k
) {
$params = $methods[$i]->getParameters();
for(
$l = 0, $call = true;
$l < $k && $call;
$l++
)
$call = call_user_func(array(new ReflectionObject($arguments[$l]), 'getName')) === $params[$l]->getClass()->name;
if($call)
return call_user_func_array(array($this, $methods[$i]->name), $arguments);
}
}
throw new Exception('Unable to find method '.$method.' with specified overload');
}
}
class Example1 extends TypeHintOverloadable {
protected function doSomething0(A $a) {
return 'Recieved an A instance with value: '.$a;
}
protected function doSomething1(B $b) {
return 'Recieved a B instance with value: '.$b;
}
protected function doSomething2(A $a, B $b) {
return $this->doSomething($a).' and '.$this->doSomething($b).' too';
}
protected function doSomething3(B $b, A $a) {
return $this->doSomething($b).' and '.$this->doSomething($a).' too';
}
public function getName(){
return 'Example1';
}
}
class Example2 extends TypeHintOverloadable {
private $name = 'Example2';
public function doStuff1(){
return $this->name;
}
public function doStuff2(Example2 $instance){
return $instance->doStuff();
}
public function doStuff3(Example1 $instance) {
return $instance->getName();
}
protected function copyName1(Example2 $instance){
$this->name = $instance->doStuff();
}
protected function copyName2(Example1 $instance){
$this->name = $instance->getName();
}
public function newName($Example1_OR_Example2){
$this->copyName($Example1_OR_Example2);
}
}
// tests
class A{
private $value;
function __construct($value){
$this->value = $value;
}
function __toString(){
return ''.$this->value;
}
}
class B extends A{}
$o = new Example1();
$a = new A('test one');
$b = new B('test two');
echo $o->doSomething($a), '
',
$o->doSomething($b), '
',
$o->doSomething($a, $b), '
',
$o->doSomething($b, $a), '
';
$o2 = new Example2();
$o3 = new Example2;
echo $o2->doStuff(), '
',
$o2->doStuff($o), '
',
$o2->doStuff($o3), '
';
$o2->newName($o3);
$o2->newName($o);
echo $o2->doStuff().'<hr />';
echo $o2->noWay();
?>
... facile? ... Overload con Type Hinting