3

この時点で、次のようなクラスがあるとしましょう。

class Sentence {
  __construct($content) {
    $this->content = $content;
  }
  public function grab_word($num) {
    $words = explode(" ", $this->content);
    return $words[$num+1];
  }
}

したがって、指定されたインターフェイスを使用するnew Sentenceと、を作成できます。次に、クラスメソッドを呼び出して、grab_word()文内の単語をフェッチできます。

$sentence = new Sentence("Lorem ipsum dolor sit amet");
echo $sentence->grab_word(2);

ただし、私がやりたいのは、別の連鎖クラスメソッドを追加して、この単語を大文字にする機能を提供することです。

$sentence->grab_word(2); # -> ipsum
$sentence->grab_word(2)->caps(); # -> IPSUM

チェーンメソッドはオブジェクトの継承を必要とするため、明らかにこれは機能しません。その関数を作成caps()してチェーンすると、継承されたオブジェクトではないため、エラーが返されSentenceます。

要約すると、私の質問は、これらのメソッドをオプションでチェーンする機能を実現する方法ですが、必要に応じて(出力例のように)非オブジェクトを返します。

4

3 に答える 3

4
class Sentence {
  function __construct($content) {
    $this->content = $content;
  }
  public function grab_word($num) {
    $words = explode(" ", $this->content);
    return new Sentence($words[$num+1]);
  }
  public function caps() {
    return new Sentence(strtoupper($this->content));
  }
  function __toString(){
      return $this->content;
  }
}

ただし、__ toStringメソッドを持つオブジェクトは、文字列と完全に互換性があるわけではありません。それはまだオブジェクトですが、文字列コンテキストで明示的に使用されると文字列に変換されます。

于 2012-06-09T00:26:04.687 に答える
3

大まかに言えば、あなたが求めていることは不可能です。メソッド呼び出しをチェーンする必要があるオブジェクトを常に返すだけではどうでしょうか。戻るだけnew Word($words[ ... ])で、より良いポジションになります。

さて、私が「大まかに言えば」と言うとき、異なるクラスに住んでいる可能性のある異なるメソッドを呼び出すことを可能にするためにあなたができることがあります。__call()実際にはかなり劣っていますが、ルビーのミックスインに似たものを実装 するために利用できます。__call()呼び出されたメソッド名を確認し、可能なターゲットのリストを繰り返して、そのオブジェクトに呼び出しを委任する(または例外を発生させる)前に、それらがそのメソッドに応答するかどうかを確認します。

PS:この質問は、継承とは何の関係もありません。メソッドチェーンでは、継承階層を実装するだけでなく、オブジェクトを返す必要があります。もちろん、$thisそれが理にかなっている場合は、を返すことができますが、通常は別のオブジェクトを返します。

于 2012-06-09T00:22:22.147 に答える
2

文字列をオブジェクトとして扱う一部の言語では、実行したいことはかなり論理的です。PHPはPerlとCに触発されており、設計上「文字列」はオブジェクトではありません。

あなたはそれをクラスにカプセル化するオブジェクトにすることができます:

class Word {
    private $content;
    function __construct($content){
        $this->content=$content;
    }
    function __toString(){
        return $this->content;
    }
    function caps(){
        strtoupper($this->content);
        return $this;
    }
}

class Sentence {
    function grab_word($num)
        $words = explode(" ", $this->content);
        return new Word($words[$num+1]);
    }
}

@chrisによる回答も、わずかに異なる実装を提供するため、確認する必要があります。リソースの浪費であり、PHPの設計はサーバーからの迅速で正確な応答に重点を置いているため、明示的なクローン作成なしで新しいオブジェクトインスタンスを作成しないことをお勧めします。

于 2012-06-09T00:36:21.007 に答える