Несколько конструкторов в абстрактном классе - PullRequest
0 голосов
/ 04 ноября 2018

У меня есть абстрактный класс (упрощенно для демонстрации):

abstract class MyClass {

    protected $id = "";
    protected $title = "";

    function __construct($title) {
        $this->id = strtolower($title);
        $this->titulo = $title;
    }

    abstract function render();
}

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

static function create($id, $title) {
    $instance = new self($title);
    $this->id = $id;
    return $instance;
}

Это прекрасно работает в обычных классах, но не работает с абстрактными классами, подобными приведенным выше. Например, когда вы делаете что-то вроде $myclass = MyClass::create("id", "title");, я получаю сообщение об ошибке:

Исключение: невозможно создать экземпляр абстрактного класса MiClase

это происходит в строке $instance = new self($title); и имеет смысл, поскольку оно пытается создать экземпляр собственного класса, который является абстрактным классом, что недопустимо.

Возможно ли иметь альтернативные конструкторы для абстрактных классов в PHP?

Ответы [ 2 ]

0 голосов
/ 04 ноября 2018
<?php

abstract class MyClass
{
    protected $id    = '';
    protected $title = '';

    public function __construct(...$array)
    {
        switch (count($array))
        {
            case 2: $this->title = $array[1];
            case 1: $this->id    = $array[0]; break;
        }
    }
}

2-й способ (для более старых версий PHP): вы можете заменить ...$array на func_get_args внутри тела функции (метода) для доступа к списку переданных переменных.

3-й способ: вы можете использовать простые массивы для передачи произвольного числа настроек.

0 голосов
/ 04 ноября 2018

Вот небольшой подход:

<?php

abstract class MyClass {

    protected $id = "";
    protected $title = "";

    function __construct($title) {
        $this->id = strtolower($title);
        $this->title = $title;
    }

    static function createWithTitle($title) {
        $instance = new static($title);
        return $instance;
    }

    static function createWithIdAndTitle($id, $title) {
        $instance = new static($title);
        $instance->id = $id;
        return $instance;
    }

    abstract function render();
}

class Concrete extends MyClass {
    function render() {
        var_dump('id=' . $this->id, 'title=' . $this->title);
    }
}

Concrete::createWithTitle('Title')->render();

Concrete::createWithIdAndTitle(1, 'Title')->render();

Обратите внимание, что здесь очень важно ключевое слово static вместо self см. Поздние статические привязки

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...