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、 だけが必要な場合もあれば、両方が必要な場合もありますBfetchData実行時にオーバーライドする方法はありますか? $.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()andがありますrunkit_method_add()が、どちらも実験的で醜いです (匿名関数のような Closure オブジェクトではなく、コード文字列を取ります)。

于 2012-07-16T22:03:37.307 に答える
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();

$thisサポートには PHP 5.4 が必要です。しかし、JavaScript には「本物の」オブジェクト指向プログラミングがないため、人々はそのようなことを JavaScript で行うことに注意してください。JavaScript、Ruby、Python などをエミュレートするためだけにエミュレートしようとするべきではありません。

明確にするために: PHP では、おそらく、継承、構成、または依存性注入が、実行しようとしている適切な方法です。(上記のハックは絶対にべきことではありません。)

于 2012-07-16T22:14:22.800 に答える
0

あなたが何をしようとしているのかは私にははっきりしていませんが、PHPでは、クラスB宣言を次のように書くことで、cals 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 に答える