[英]PHP OOP classes and functions
我不确定如何命名,但是就此开始。 假设我有以下内容
class A {
public function aa() {
$this->bb();
}
public function bb() {
}
}
class B extends a {
}
class C {
__construct(B $service) {
$this->service = $service;
}
public function aa() {
$this->service->aa();
}
}
我的代码调用将是
$C = new C(new B());
$C->aa();
因此,这基本上将执行我想要的A:aa()
。 如您所见,在A::aa()
中将调用AA::bb()
。
我需要的。 调用AA :: bb()时,我想执行C类中定义的某些代码,但不允许更改A类。 我只能更改B类或C类。
我的想法是在B类中添加一个侦听器并像这样覆盖bb()函数
class B extends a {
public $listener;
bb() {
parent::bb();
$this->listener();
}
}
class C {
__construct(B $service) {
$this->service = $service;
}
public function aa() {
$this->service->listener = function() { }
$this->service->aa();
}
}
但是我不太喜欢这个主意,看起来也不是一个好主意。 我在这里有什么选择?
同样,我不能更改A类,而我只能调用C类。
PHP版本是5.3
您有两个选择。 延伸或装饰。
第一个有点像您已经编写的内容,但是,我不会对侦听器使用public
可见性:
class Foo extends A {
private $listener;
public function setListener(callable $func) {
$this->listener = $func;
}
public function bb() {
call_user_func($this->listener);
return parent:bb();
}
}
在该示例中,我通过setter注入传递了侦听器,但是您也可以使用构造函数注入,并在重载的__construct()
方法中传递$listened
__construct()
。 扩展类时,“接口限制”不适用于构造函数的签名。
另一种方法是使用装饰器:
class Foo {
private $target;
public function __construct(A $target) {
$this->target = $target;
}
public function bb($callback) {
$callback();
return $this->target->bb();
}
public function __call($method, $arguments) {
return call_user_func_array(
array( $this->target, $method ),
$arguments
);
}
}
第二种方法是让您更改界面。
您选择哪个选项取决于您实际需要实现的确切功能。 装饰器是一种解决方案,用于当您需要对对象行为进行彻底更改时-例如,对于添加访问控制而言,它真的很好。
我了解您要在A
代码完成后在C
执行代码。 您不能更改A。
如所写, C::aa
调用A::aa
,后者调用A::bb
并展开堆栈。 为什么在服务调用结束后不仅仅在C::aa
工作?
class C {
public function aa() {
$this->service->aa();
// whatever you want to do
}
}
另一方面,如果您需要在调用A::aa
之后但在调用A::bb
之前调用代码,那么您发布的示例就足够清楚了:
class B extends a {
public $listener;
public function bb() {
call_user_func($this->listener);
parent::bb();
}
}
注意使用call_user_func
,这是PHP 5.3调用存储在成员变量中的匿名函数所必需的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.