php - 为什么 PHP 允许您在构造函数上重载类型提示,但不允许在方法上重载类型提示?

标签 php

假设你有这个:

<?php

interface Type
{}

class SomeType implements Type
{}

class SomeOtherType implements Type
{}

现在,如果您有一个将 Type 接口(interface)作为构造函数依赖项的抽象类,如下所示:

<?php

abstract class TypeUser
{
        public function __construct(Type $type)
        {}
}

为什么 PHP 允许您像这样在具体类上重载构造函数:

<?php

class SomeTypeUser extends TypeUser
{
        public function __construct(SomeType $type)
        {}
}

class SomeOtherTypeUser extends TypeUser
{
        public function __construct(SomeOtherType $type)
        {}
}

但它不允许您对方法执行相同的操作,只能对构造函数执行此操作 — 如果您尝试对非构造函数方法执行此操作,PHP 会抛出一个严格标准错误吗?

最佳答案

请阅读:Override method parameter with child interface as a new parameter

TL;DR:如果您使用较窄 类型重载方法参数类型,方法签名会更改并与父方法不兼容。您不能用任意子类替换 TypeUser 的实例,因为重载子类的方法签名与父类的方法签名不兼容,因此没有给出调用此类实例的稳定、已知的接口(interface)。

为什么它适用于构造函数?因为要构造一个实例,您(通常)会对其类名进行硬编码:

$user = new SomeTypeUser($parameter);

这里没有歧义构造函数需要什么参数,你确切地知道你正在实例化什么类。

然而,这里不是这样的:

function (TypeUser $user) {
    $user->foo($something);
}

那么,$user 是哪个类的实例? SomeTypeUser? SomeOtherTypeUser?完全不同的东西? $user->foo() 的签名是foo(SomeType $type) 还是foo(SomeOtherType $type)?上面的代码会不会在运行时爆炸?谁知道...

关于php - 为什么 PHP 允许您在构造函数上重载类型提示,但不允许在方法上重载类型提示?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24803939/

相关文章:

php - CSV 或 Mysql 用于静态数据?

php - 使用 PHP/MySQLI/Apache 时在哪里安全地存储证书/ key ?

php - 如何检查索引是否存在并且在php中不为空

php - 如何解码json ajax响应

php - 亚马逊产品 API 和多个潜在类别的准确性

php - WooCommerce 自定义循环按名称而不是 Slug

PHP - 获取 XML 节点的值

php - php 文件中的动态跨度类。

php - MySQL 中的算术运算

php - 使用 Ion Auth 在 Codeigniter 中创建用户角色和配置文件