Вызов методов родительского класса - PullRequest
5 голосов
/ 09 января 2010

Вопрос отредактирован, чтобы лучше отражать мои потребности.


Возьмите следующий пример:

class Base
{
    public $Text = null;

    public function __construct()
    {
        $this->Text = new Base_Text();
    }
}

class Base_Text extends Base
{
    public $Is = null;

    public function __construct()
    {
        $this->Is = new Base_Text_Is();
    }

    public function CammelCase($string)
    {
        return trim(str_replace(' ', '', ucwords($string)));
    }
}

class Base_Text_Is extends Base_Text
{
    public function CammelCase($string)
    {
        return ($string === $this->CammelCase($string)); // doesn't work
    }
}

Как мне исправить метод Base_Text_Is::CammelCase() без статического вызова класса Base_Text (без использования parent:: или Base_Text::)?

Единственное решение, которое я придумал для подобных ситуаций, - это создать одноэлементную функцию, подобную этой:

function Base()
{
    static $instance = null;

    if (is_null($instance) === true)
    {
        $instance = new Base();
    }

    return $instance;
}

И измените метод Base_Text_Is::CammelCase() на этот:

return ($string === Base()->Text->CammelCase($string));

И чтобы не создавать два экземпляра объекта базового класса, вместо этого:

$base = new Base();
$base->Text->Is->CammelCase('MethodOverloading'); // true

Я просто делаю:

Base()->Text->Is->CammelCase('MethodOverloading'); // true

Это хорошая практика? Есть ли другие решения?

Ответы [ 2 ]

7 голосов
/ 09 января 2010

Суть вашего вопроса лежит здесь:

Как Сын :: B () может вызвать папу :: A () метод нестатически (без использования родитель или папа)?

Ответ прост: не может. Вы преодолели Dad::A() с Son::A(). Единственная концепция A(), которую сейчас имеет объект Son, - это собственная A(). Вы должны вызывать родительский метод статически или для совершенно другого Dad экземпляра объекта.

Суть в том, что если вы хотите вызвать родительский метод A(), зачем вам вообще переопределять его?

Ваша структура также не имеет никакого смысла. Почему вы хотите, чтобы звонок на $dad->A() передавался на $dad->son->A(), который, в свою очередь, вызывал бы $dad->son->B(), который затем из того, что вы спрашиваете, снова вызывал бы $dad->A()? Это бесконечный цикл.

Ваш одноэлементный подход, похоже, не дает никаких реальных преимуществ, кроме того, что вы не создаете экземпляры более чем одного объекта папы, но факт заключается в том, что вы все еще создаете совершенно отдельный объект для выполнения логики, которая звучит как эта должен быть внутри класса, а не снаружи.

Не видя реальной логики и того, что вы пытаетесь достичь, трудно понять, что порекомендовать, чтобы избежать этой круговой зависимости. Однако я думаю, что вы, возможно, захотите проанализировать, что вы пытаетесь сделать с помощью этих методов, и, возможно, изменить дизайн работы наследования.

EDIT

Я думаю, у вас слишком много наследства. Нет причины, по которой вы должны делать это:

$base = new Base();
$base->Text->Is->CammelCase('MethodOverloading'); // true

Если все функции в дочерних классах, вам не следует создавать экземпляр класса Base. Должно быть что-то вроде этого:

$text = new Text();
$text->isCamelCase('someString');

Ваш код может быть значительно упрощен, при этом все циклические родительские / дочерние экземпляры удалены, а специальные функции переданы дочерним классам:

class Base
{
    //don't put anything related to child classes here,
    //unless it is going to provide specific functionality
}

class Text extends Base
{
    public function CamelCase($string)
    {
        return trim(str_replace(' ', '', ucwords($string)));
    }

    public function isCamelCase($string)
    {
        return ($string === $this->CamelCase($string));
    }
}
1 голос
/ 09 января 2010

Я не думаю, что есть способ вызвать родительский метод от ребенка, не вызывая его статически или используя parent::. Возможно, я неправильно понимаю вопрос. Создание экземпляра Son () не создает двух объектов. Сын расширяет папу, но это все еще один объект.

Если вы собираетесь вызывать Папу () с Синглтоном внутри Сына, тогда зачем расширять его от Сына?

...