2012-06-09 28 views
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对象,它将返回一个错误。总结起来,我的问题是如何实现链接这些方法的能力,但仍然会在需要时返回一个非对象(就像我的输出示例中那样)。

+0

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

回答

3

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

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

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

+1

我希望我可以选择所有的答案,但你首先提供了一个全面的解释,所以我会接受你的答案。非常感谢您的见解/提示! (我也投票赞成所有有用的答案) –

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方法的对象isnt完全与字符串兼容。它仍然是一个对象,但是,它会在字符串上下文中明确使用时转换为字符串。

+0

或创建一个单词类,使句子和word.class.php都继承一个编码良好的字符串类,因此内部方法可用于所有字符串返回 – IEnumerable

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]); 
    } 
} 

你也应该看看答案通过@克里斯,因为它为您提供了略有不同的实现。我建议你不要在没有显式克隆的情况下创建新的对象实例,因为这浪费了资源,PHP的设计侧重于服务器的快速而精确的响应。