我们遇到了问题[cit。]
我需要在一个变量param的基础上动态地在一个类中分配一个回调:我的目标是让只有一个类(而不是一个主类和许多扩展子类),如果值为X,则在此类中,则必须使用funcitonX,如果为Y,则为functionY。
我知道我无法解释清楚,我希望我的榜样能够做到:
class plzComplicateMyLife{
public $vehicle;
public $kindVehicle;
public $dynamicFunction;
public function __construct($vehicle, $kindVehicle){
$this->kindVehicle = $kindVehicle;
$this->vehicle = $vehicle;
switch($kindVehicle){
case 'cycle':
$this->dynamicFunction = "isACycle";
break;
case 'car':
$this->dynamicFunction = "isACar";
break;
}
//here come the problem, i need to call the callback store in dynamicFunction.
//i tried:
//call_user_func($this->$this->dinamicFunction, $this->vehicle);
//error: Catchable fatal error: Object of class plzComplicateMyLife could not be converted to string in [...]
//call_user_func("plzComplicateMyLife::".$this->dynamicFunction);
//Warning: call_user_func(plzComplicateMyLife::isACar) [function.call-user-func]: First argument is expected to be a valid callback in [...]
//$this->dynamicFunction();
//Fatal error: Call to undefined method plzComplicateMyLife::dynamicFunction() in [...]
//so, how can i do that?
}
public function isACycle($vehicle){
echo 'im a cycle, model: '.$vehicle.'<br />';
}
public function isACar($vehicle){
echo 'im a car, model: '.$vehicle.'<br />';
}
//i know this has no sense, in this example at least.
public function printKind(){
//call_user_func($this->$this->dinamicFunction, $this->vehicle);
//call_user_func("plzComplicateMyLife::".$this->dynamicFunction);
//then?
}
}
$maserati = new plzComplicateMyLife('maserati4', 'car');
//then, maybe, outside the class i'll need to recover the callback:
$maserati->printKind();
修改:
Rob说,多态性确实是一个很好的解决方案。
但问题是,在这种情况下,我真的必须对每个类实例都有相同的声明,只更改参数......例如:
$maserati = new plzComplicateMyLife('maserati4', 'car');
$ducati = new plzComplicateMyLife('maserati4', 'cycle');
//is good
//becose i cant have:
$maserati = new plzComplicateMyLifeWithACar('maserati4');
$ducati = new plzComplicateMyLifeWithACycle('maserati4');
答案 0 :(得分:2)
多态性是这里的方法,但为了将来参考,您也可以这样做:
public function printKind() {
$this->{$this->dynamicFunction}($this->vehicle);
}
答案 1 :(得分:1)
在PHP中,您可以使用数组作为回调变量(see here)来指定方法回调,例如:
array( $object, $methodName );
所以你可以这样做
$callback = array($this, $this->dynamicFunction);
call_user_func($callback, $this->vehicle);
答案 2 :(得分:1)
呃,为什么不你想在这里使用简单的继承结构?如果你想根据建模的对象想要不同的行为,那么这就是多态的规范描述。
如果你确实想要将回调放到同一个对象中,那么你需要做两件事之一:
从您的回调中删除$vehicle
参数,将其设为私有或受保护,并正常调用它们,即
call_user_func( array( $this, 'isACycle' ) );
将回调标记为静态,将其设为私有或受保护,并按如下方式调用它们:
call_user_func( array( __CLASS__, 'isACycle' ), $this );
在非静态回调中,以正常方式通过$this
访问对象的属性。另请注意,我建议将回调标记为私有或受保护,以防止不必要的外部呼叫者;大概,你不希望他们为每种类型执行错误的方法。
答案 3 :(得分:1)
为了回应你的编辑,你不能做这样的事吗?
abstract class MethodOfTransport {
protected $model;
public function __construct($model) {
$this->model = $model;
}
abstract public function printKind();
public static function create($model, $type) {
$object = new $type($model);
return $object;
}
}
class cycle extends MethodOfTransport {
public function printKind() {
echo 'im a cycle, model: '.$this->model.'<br />';
}
}
class car extends MethodOfTransport {
public function printKind() {
echo 'im a car, model: '.$this->model.'<br />';
}
}
$maserati = MethodOfTransport::create('maserati4', 'car');
$maserati->printKind();
$ducati = MethodOfTransport::create('maserati4', 'cycle');
$ducati->printKind();