PHP: Как решить проблему перегрузки метода в подклассе (объявление ... должно быть совместимо с)? - PullRequest
0 голосов
/ 13 ноября 2018

Пример должен продемонстрировать это лучше всего:

class Generic {
    protected $a;
    protected $b;

    protected final function __construct($a,$b) {
        $this->a = $a;
        $this->b = $b;
        echo $this->a." ".$this->b;
    }

    public static function create($a,$b) {
        return new self($a,$b);
    }


}

class Wanter extends Generic {
    public static function create($b) {
        return parent::create("I want",$b);
    }
}

Generic::foo("I need","coffee!");
Wanter::foo("coffee!");

Ожидаемый результат:

I need coffee!I want coffee!

Фактический объем производства:

Предупреждение : объявление Wanter :: create ($ b) должно быть совместимым с Generic :: create ($ a, $ b) в [...] [...] в строке 25 Мне нужен кофе! Я хочу кофе!

Очевидно, что это должно делать (как оно и делает). Однако я хочу запустить это без предупреждения конечно. Как реализовать это без предупреждения?

1 Ответ

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

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

Я бы сделал следующее:

class Generic {
    protected $a;
    protected $b;

    protected final function __construct($a,$b) {
        $this->a = $a;
        $this->b = $b;
        echo $this->a." ".$this->b;
    }

    public static function create($a,$b) {
        return new self($b,$a); //reverse arguments
    }


}

class Wanter extends Generic {
    public static function create($a, $b="I want") {
        return parent::create($b,$a);
    }
}

Обратите внимание, чтоЯ изменил порядок аргументов, так что аргумент со значением по умолчанию является вторым аргументом.

Вы можете сделать это только в дочернем элементе, но это может несколько запутать, если порядок отличается от родительского.class.

Тем не менее, в данном случае более подходящим может быть что-то вроде фабричного метода.

https://en.wikipedia.org/wiki/Factory_(object-oriented_programming)

Помимо фабричного шаблона, я не увереннасколько важно для вас иметь статический метод Create.Конструктор предлагает больше гибкости, когда нужны такие вещи, как полиморфизм.Например, что-то вроде этого было бы приемлемо

abstract class Generic {
   protected $a;
   protected $b;

   protected function create($a,$b) {
        $this->a = $a;
        $this->b = $b;
        echo $this->a." ".$this->b;
    }

}

class Wanter extends Generic {
    public function __construct($a) {
        return $this->create("I want",$a);
    }
}

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

...