PHP:使用父类作为接口(interface)中的类型声明

标签 php oop

假设我有一个从“模型”扩展而来的特定模型

Class MyModel extends Model { ... }

对于每个模型,我想创建一个实现 TranslatorInterface 的 Translator 类

Interface TranslatorInterface {
    public function translate(Model $model);
}

但是我不想传递父类“Model”,而是想将确切的模型子级传递给翻译方法

Class MyTranslator implements TranslatorInterface {
    public function translate(MyModel $model) { 
        ... 
    }
}

我无法让这个工作。

我知道我可以通过以下方式解决这个问题

Class MyTranslator implements TranslatorInterface {
    public function __construct(MyModel $model) {
        $this->model = $model;
    }

    public function translate() {
        $this->model->doSomething();
        ...
    }
}

接口(interface) __construct 方法未定义,translate() 方法也不会接收任何参数。

但我想知道是否有可能像我上面尝试的那样完成它。(如果没有,这就是为什么这是一个坏主意;))

最佳答案

这是被禁止的,因为它违反了 Liskov Substitution Principle :

Contravariance of method arguments in the subtype.

这意味着该方法可以更改,但前提是您扩大了类型限制。目前PHP不支持real contravariance 。这时候就只能用简单的parameter type widening -- 意味着在接口(interface)的实现中你可以省略参数类型。

关于PHP:使用父类作为接口(interface)中的类型声明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51821121/

相关文章:

php - PHP 中\s 匹配的空格是什么?

JavaScript 改变 this 的所有权

c++ - 如何构建遗传算法类层次结构?

java - 如何创建启动 Activity 的方法?

javascript - PHP 或 Javascript 通过元素 ID 单击或选择框架中的元素

PHP SQL 语句不工作

php - CodeIgniter:json_decode 数组问题

php - laravel Eloquent 查询中的位置不适用于两个数组

objective-c - OO设计和核心数据: Where to put aggregate calculation method?

c# - 如何在从 ObservableCollection<T> 派生的运行时创建类的实例?