... 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 $aB $b) {
        return 
$this->doSomething($a).' and '.$this->doSomething($b).' too';
    }
    
    protected function 
doSomething3(B $bA $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 
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