【问题标题】:OOP Method chaining optional returnOOP 方法链可选返回
【发布时间】:2012-06-09 00:11:32
【问题描述】:

此时,假设我有一个这样的课程:

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

总而言之,我的问题是如何实现可选地链接这些方法,但在需要时仍返回非对象(如在我的输出示例中)。

【问题讨论】:

  • 简短:你不能。复杂:您可以制作一个对象来携带当前转换的值,然后实现__toString() 以在需要时将该对象隐式转换为字符串。当然不值得努力。

标签: php oop inheritance chaining


【解决方案1】:
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 方法的对象与字符串并不完全兼容。它仍然是一个对象,但是在字符串上下文中显式使用时会转换为字符串。

【讨论】:

  • 或创建一个单词类,因此句子和 word.class.php 都继承了一个编码良好的字符串类,因此可以在所有字符串返回上使用内部方法
【解决方案2】:

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

现在,当我说“广义而言”时,您可以做一些事情来调用不同的方法,这些方法可能存在于不同的类中。你可以使用__call() 来实现类似于ruby 的mixin 的东西,虽然真的很差。 __call() 将简单地查看被调用的方法名称,然后迭代可能的目标列表并查看它们是否响应该方法,然后将调用委托给该对象(或引发异常)。

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

【讨论】:

  • 我希望我能选择所有的答案,但你先提供了一个全面的解释,所以我会接受你的。非常感谢您的见解/提示! (我也对所有有用的答案进行投票)
【解决方案3】:

在某些将 String 视为对象的语言中,您想要做的事情是相当合乎逻辑的。 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 的设计侧重于服务器的快速准确响应。

【讨论】:

    猜你喜欢
    • 2014-11-13
    • 2011-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-22
    • 2015-01-08
    • 2020-09-23
    相关资源
    最近更新 更多