0

好的,我知道这可能是不可能的,但我会试一试。也许我的知识不是那么好。请不要投反对票,这只是出于好奇,这可能是由于糟糕的 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在运行时覆盖的方法?我的意思是$.extend()jQuery 中的一些东西:

$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
4

3 回答 3

1

没有适当的方法来修改/替换/添加类方法。

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

于 2012-07-16T22:03:37.307 回答
0

我不清楚您要做什么,但是在 PHP 中,您可以通过编写 B 类声明来让 calss B 扩展 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
}

希望这可以帮助。

于 2012-07-16T22:09:14.703 回答
0

最简洁的答案是不。

最接近您所要求的内容是:

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 中,继承或组合或依赖注入可能是您尝试做的事情的正确方法。(上面的 hack 绝对不是你应该做的。)

于 2012-07-16T22:14:22.800 回答