Я пытаюсь создать класс Developer
, который является подклассом Person
.
Я хочу, чтобы они оба использовали статический шаблон фабрики (или «именованные конструкторы»).
Я видел несколько примеров этого паттерна, но ни один из них не использует наследование.
Вопрос 1
В примерах они делают метод конструктора всегда закрытым.
Можно ли сделать его защищенным для вызова из дочернего конструктора?
Или я должен решить проблему, делая конструкторы всегда закрытыми и пытаясь построить наследование, вызывая метод create
родителя из метода create
дочернего элемента?
Вопрос 2
Когда я пытаюсь создать экземпляр класса Person или Developer, я получаю сообщение об ошибке ниже. Почему?
PHP Fatal error: Declaration of Developer::create(string $name, string $surname, ?int $yearsOfExperience = NULL, ?string $preferredLanguage = NULL): Developer must be compatible with Person::create(string $name, string $surname): Person in InheritanceTest.php on line 57
Это работает, когда я удаляю подсказки типа : self
в обоих методах create
, но я не понимаю, почему они несовместимы, если Developer
является дочерним классом Person
.
Заранее спасибо.
<?php
class Person
{
protected $name;
protected $surname;
protected function __construct(string $name, string $surname)
{
$this->name = $name;
$this->surname = $surname;
}
public static function create(string $name, string $surname): self
{
// Some validation
if($name == ''){
throw new InvalidArgumentException('A person name can not be empty.');
}
if($surname == ''){
throw new InvalidArgumentException('A person surname can not be empty.');
}
return new self($name, $surname);
}
}
class Developer extends Person
{
protected $yearsOfExperience;
protected $preferredLanguage;
protected function __construct(string $name, string $surname, ?int $yearsOfExperience, ?string $preferredLanguage)
{
parent::__construct($name, $surname);
$this->yearsOfExperience = $yearsOfExperience;
$this->preferredLanguage = $preferredLanguage;
}
public static function create(string $name, string $surname, ?int $yearsOfExperience = null, ?string $preferredLanguage = null): self
{
// Some validation
if($yearsOfExperience < 0){
throw new InvalidArgumentException('The years of experience can not be negative.');
}
if($preferredLanguage == ''){
throw new InvalidArgumentException('The preferred language can not be empty.');
}
return new self($name, $surname, $yearsOfExperience, $preferredLanguage);
}
}