PHP函数多态性

PHP函数多态性,php,Php,我想在我的类中使用函数多态性。我打算为我的一些子类函数检查函数的输入类型 class A { public function setValue(Type $value) { } } class B extends A { public function setValue(XType $value) { } } class C extends A { public function setValue(ZType $value) {

我想在我的类中使用函数多态性。我打算为我的一些子类函数检查函数的输入类型

class A
{
    public function setValue(Type $value)
    {
    }
}

class B extends A
{
    public function setValue(XType $value)
    {
    }
}

class C extends A
{
    public function setValue(ZType $value)
    {
    }
}
$b = new B();
$b->setValue(new XType());

我要寻找的行为是,如果使用错误的参数类型调用setValue,PHP会抛出异常

如果我使用上述代码,我会得到一个错误:

运行时注意:B::setValue()的声明应该与B.php行中的A::setValue(类型$value)兼容

这就是我如何获得我想要的行为:

class B extends A
{
    public function setValue(Type $value)
    {
        if (!$value instanceof XType) {
            throw new \Exception("value $value not allowed, should be of type XType");
        parent::setValue($value);
        }
    }
}
但我很乐意让PHP核心为我处理这段代码:)

我看我不够清楚


我试图为调用者提供默认行为a::setValue(),以及关于某些子类的特定行为B::setValue(),因此,如果调用者尝试使用不受支持的类型调用B::setValue(),它将得到一个错误,但是如果它调用,比如说,D::setValue(),它将得到默认值a::setValue().

您已经完成的工作,不需要检查您正在执行的操作的
实例。您只需在参数类型提示中声明类型

代码的错误在于它不是正确的多态性。这也是通知(注意:不是错误)想要告诉你的。子类需要与父类不同的参数类型。即使这些类型是相关的,也意味着您不能用一个子类替换父类的任何给定实例。这就是打破多态性的原因。如果您的子类需要更特殊的类型,那么它们的声明将不再与其父类兼容,因此它们不是完全多态的

在适当的多态性中,这应该起作用:

if (rand(0, 1)) {
    $obj = new A;
} else {
    $obj = new B;
}

$obj->setValue(new Type);

如果您尝试执行的操作将不起作用。

您已经执行的操作,则不需要检查您正在执行的操作的
实例。您只需在参数类型提示中声明类型

代码的错误在于它不是正确的多态性。这也是通知(注意:不是错误)想要告诉你的。子类需要与父类不同的参数类型。即使这些类型是相关的,也意味着您不能用一个子类替换父类的任何给定实例。这就是打破多态性的原因。如果您的子类需要更特殊的类型,那么它们的声明将不再与其父类兼容,因此它们不是完全多态的

在适当的多态性中,这应该起作用:

if (rand(0, 1)) {
    $obj = new A;
} else {
    $obj = new B;
}

$obj->setValue(new Type);

用你想做的事情是行不通的。

Lol,是的!我想知道是否有一种方法可以实现我在没有instanceof part的情况下获得的相同行为:)方法参数类型是逆变的。哈哈,是的!我想知道是否有一种方法可以实现我在没有instanceof part的情况下获得的相同行为:)方法参数类型是反变的。。。我应该更具体地说明我的需要,我会编辑我的问题,谢谢!我明白你想做什么,但答案没有真正的区别。:)您不应该缩小或更改函数在其子函数中接受的类型。我理解这是一个很容易的诱惑,但问问自己为什么要这样做。您显式地使某些类依赖于某些其他类。这是两条遗传链耦合在一起。如果它们有如此密切的关系,为什么它们不在同一个类中,或者一开始就显式地耦合在一起?也许这有一个合理的用例,但是如果真的需要,请先考虑一下。我没有在类中声明类型,因为该类型在不同的类中使用。。为了让您了解我试图实现的目标,请看一看我试图将所有属性和属性类型映射到OO样式的类。属性表示我的类A、B、C和属性类型XType、YType等。我想确保A使用的是正确的类型为什么要将“属性”和“属性类型”区分为两个独立的类层次结构?在我看来,属性是一种类型。您可以有许多不同的
抽象
父类,它们表示类型(
Double
ArrowType
,…),并具有具体的属性
扩展这些类型(
阻尼扩展Double
Arrowtail扩展ArrowType
)。这似乎能更好地模拟需求。我都没想过!我会尝试一下,让你知道这是否适合我的需要。我明白你的意思。。。我应该更具体地说明我的需要,我会编辑我的问题,谢谢!我明白你想做什么,但答案没有真正的区别。:)您不应该缩小或更改函数在其子函数中接受的类型。我理解这是一个很容易的诱惑,但问问自己为什么要这样做。您显式地使某些类依赖于某些其他类。这是两条遗传链耦合在一起。如果它们有如此密切的关系,为什么它们不在同一个类中,或者一开始就显式地耦合在一起?也许这有一个合理的用例,但是如果真的需要,请先考虑一下。我没有在类中声明类型,因为该类型在不同的类中使用。。为了让您了解我试图实现的目标,请看一看我试图将所有属性和属性类型映射到OO样式的类。属性表示我的类A、B、C和属性类型XType、YType等。我想确保A使用的是正确的类型为什么要将“属性”和“属性类型”区分为两个独立的类层次结构?在我看来,属性是一种类型。您可以有许多不同的
抽象
父类,它们表示类型(
Double
ArrowType
,…),并具有具体的属性
扩展这些类型