php - 我可以实现接口并覆盖接口方法之一的返回类型吗?
问题描述
我有一个Task
扩展抽象类的类,TaskBase
.
// class Task
class Task extends TaskBase {
/**
* @var Processor
*/
private $processor
public function __construct(Processor $processor)
{
$this->processor = $processor;
}
public function process() : ProcessResult
{
return $this->processor->execute();
}
}
// abstract class TaskBase
abstract class TaskBase implements CommanTask {
protected function getKey(): string
{
}
}
这TaskBase
实现了一个接口CommanTask
,其中包含以下方法。
interface CommanTask {
public function process(): ProcessResult;
}
现在我需要一个新的任务类TaskMultiple
,它的process()
方法需要返回一个数组ProcessResult
而不是一个ProcessResult
。
如何TaskBase
为这个新类扩展抽象TaskMultiple
类?
解决方案
如果你实现了一个接口,你需要真正遵守接口制定的契约。
您建议的界面说process()
返回一个ProcessResult
. 如果您可以在实现类中将其更改为返回array
,则该类的使用者将无法信任接口指定的协定。
他们会尝试使用 的结果TaskMultiple::process()
,并且由于他们的接口说它将返回 a ProcessResult
,因此当它试图将其视为这样(例如,通过访问该类的方法)时,很快就会发生致命错误,但事实并非如此.
您的解决方案是:
如果您使用的是 PHP 8,则可以使用联合类型:
interface Task {
public function process(): ProcessResult|iterable;
}
它会工作,但它很丑陋。现在,任何Task
实现服务的消费者都需要检查 的结果,process()
看看它是单个ProcessResult
还是一个集合(可能是ProcessResult
s)。
如果您使用的是 PHP < 8,则只需删除类型提示即可使其工作:
interface Task {
public function process()
}
现在消费者只知道有一个process()
方法,但你根本没有类型信息。还是更丑。
更好的是,只需创建不同的接口,例如Task
and MultipleTask
:
interface Task {
public function process(): ProcessResult;
}
interface MultipleTask {
public function process(): iterable;
}
由于您BaseTask
不包含任何有助于实现该类的内容(仅包含一个抽象方法,使其与接口非常相似),因此将implements
移至每个具体任务类:
class ExampleTask extends BaseTask implements Task
{ /** implementation **/ }
class ExampleMultipleTask extends BaseTask implements MultipleTask
{ /** implementation **/ }
推荐阅读
- c# - SQL Linq:获取嵌套 DB 类的单个实例
- typo3 - TYPO3 10.3 中前端的用户名
- c# - 我不断收到此错误,但无法修复:错误 CS0161: 'Program.MathMinWhole(int, int)': 并非所有代码路径都返回值
- python-3.x - python处理文本文件中的特定部分
- scala - 什么是更好的?foreach 和更新地图与使用 list.map
- linux - 为什么 ls -1 /tmp/dir/ /and ls -1 /tmp/dir/* 不显示相同的结果
- python - 提取文件中匹配正则表达式的所有行
- angular - 无法将当前对象值传递给 Angular 9 中的同级组件
- flutter - TextFormField:仅当文本字段足够宽时才显示 suffixIcon
- r - R:使用for循环从具有多个条件的原始数据帧中删除数据帧的子集