php - 具有继承和类型提示的静态工厂模式
问题描述
我正在尝试创建一个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);
}
}
解决方案
问题一:
在示例中,它们使构造函数方法始终为私有。是否可以对其进行保护以便从子构造函数中调用?
你必须保护它。否则不允许孩子调用父母的方法。
问题2:
当我在两个创建方法中删除 : self 类型提示时它会起作用,但我不明白为什么它们不兼容,如果 Developer 是 Person 的子类。
尝试使用static
而不是self
. 它可能有效,但我不确定。但是您仍然会注意到(或警告,不记得了),因为 Developer 中的工厂方法具有与 Person 不同的参数。在 PHP 中这是允许的,但不建议这样做。
推荐阅读
- html - 现在(2020 年)自由使用 Flexbox 和 Grid 是否安全?
- javascript - 如何在 IBM Carbon(Angular)中的表上应用搜索过滤器?
- c# - OpenQA.Selenium.WebDriverException :对远程 WebDriver 服务器的 HTTP 请求 URL http://localhost :点击 90 秒后超时
- react-native - 在 react native 上使用 Google gapi 浏览器库
- javascript - DataTables 无法读取未定义的属性“行”
- c++ - 如何检查字符串或字符是否有中文字符然后显示其他字符?
- azure - 代理无法连接到服务器
- c# - 使用正则表达式去除 html,但包含字符的标签除外
- eclipse - 本地主机上的服务器 Tomcat v9.0 服务器无法启动,并且子容器在启动期间失败
- c - 将单针 Arduino LED 矩阵划分为多个扇区