OOP方法链接可选返回

时间:2012-06-09 00:11:33

标签: php oop inheritance chaining

此时,假设我有一个类似的课程:

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对象,它将返回错误。

总结一下,我的问题是如何实现链接这些方法的能力,但是在需要时仍然会返回一个非对象(比如在我的输出示例中)。

3 个答案:

答案 0 :(得分: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方法的对象与字符串完全兼容。它仍然是一个对象,但是,当在字符串上下文中明确使用时,它将转换为字符串。

答案 1 :(得分:3)

从广义上讲,你所要求的是不可能的。为什么不总是返回您有时需要链接方法调用的对象?只需返回new Word($words[ ... ]),您就会处于更好的位置。

现在,当我说"广泛地说"时,你可以采取一些措施来调用不同的方法,这些方法可能存在于不同的类中。您可以使用__call()来实现类似于ruby的mixins,但实际上非常低劣。 __call()只会查看被调用的方法名称,然后在将调用委托给该对象(或引发异常)之前迭代可能的目标列表并查看它们是否响应该方法。

PS:这个问题与继承没有任何关系。方法链接需要返回一个对象,而不仅仅是实现一个继承层次结构。当然,您可以返回$this,这有意义,但通常会返回另一个对象。

答案 2 :(得分:2)

在某些将String视为对象的语言中,您想要做的是相当合理的。 PHP的灵感来自Perl和C,而设计“string”不是一个对象。

你可以把它封装成一个类:

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的设计侧重于服务器的快速和精确响应。