在PHP中重写不带继承的实例方法


Overriding an instance method without inheritance in PHP?

好的,我知道这可能是不可能的,但我会尝试一下。也许我的知识不太好。请不要投反对票,这只是出于好奇,可能是因为OO设计不好。

假设A的类定义为:

class A
{
    public function build()
    {
        $data = $this->fetchData();
        ...
    }
    public function fetchData()
    {
        // Database eavy query
        return $this->repository->fetchDataForCharting();
    }
}

然后,在不使用良好和体面的OO设计的情况下,创建类B,该类将使用存储库中的fetchDataForCharting来进行其他一些不同的计算:

class B
{
    public $data;
    public function getMonthlyLimit()
    {
        // Database eavy query
        $data = $this->getData();
    }
    public function getData()
    {
        return isset($this->data) ? $this->data :
            $this->repository->fetchDataForCharting();
    }
}

有时你只需要A,有时你只需B,有时两者兼而有之。有什么方法可以在运行时覆盖fetchData吗?我的意思是像jQuery中的$.extend()

$b = new B();
$b->getMonthlyLimit(); // $b->data filled
$a = new A();
// Override fetchData
$a = extend($a, 'fetchData', function() use($b) { return $b->data; });
$a->build(); // Just 1 query

没有正确的方法来修改/替换/添加类方法。

runkit扩展有runkit_method_redefine()runkit_method_add(),但它们都是实验性的,而且很难看(它们采用的是代码字符串,而不是像匿名函数那样的闭包对象)。

我并不清楚你想做什么,但在PHP中,你可以让calss B通过如下方式编写class B声明来扩展class A:

Class B extends Class A {
   ...
}

您可以覆盖类B中的fetchData函数,如

public function fetchData {
    // do something different than in class A
}

public function fetchData {
    // execute the Class A functionality first
    parent::fetchData();
    // now do something in addition to what is in Class A functionality
}

希望这能有所帮助。

简短的回答是否定的。

你能最接近你所要求的是:

class A
{
  public function __construct()
  {
    $this->bar = function()
    {
    };
  }
  public function foo()
  {
    $bar = $this->bar;
    $bar();
  }
}
$a = new A();
$a->bar = function()
{
  // override
};
$a->foo();

需要PHP 5.4才能支持$this。但请记住,人们在JavaScript中做这种事情是因为它没有"真正的"面向对象编程。你不应该仅仅为了模仿JavaScript、Ruby、Python等

需要明确的是:在PHP中,继承、组合或依赖项注入可能是实现您想要做的事情的正确方法