2012-06-09 1 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, хотя и очень неплохо. __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 полностью не совместим со строкой. Это все еще объект, но он преобразуется в строку, когда явно используется в контексте строки.

+0

или создавая класс слов, поэтому оба предложения и word.class.php наследуют хорошо закодированный класс строк, поэтому встроенные методы могут использоваться для всех строк – IEnumerable

2

Что вы хотите сделать, достаточно логично на некоторых языках, которые рассматривают 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]); 
    } 
} 

Вы также должны взглянуть на ответ на @ Крис, как он предлагает несколько иной реализации. Я бы предположил, что вы не создаете новые экземпляры объектов без явного клонирования, потому что это пустая трата ресурсов, а дизайн PHP сосредоточен на быстром и точном ответе с сервера.