1

我想在我的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)
    {
    }
}
$b = new B();
$b->setValue(new XType());

class Type {};
class XType extends Type;
class ZType extends Type;

我正在寻找的行为是,如果使用错误的参数类型调用setValue ,PHP 会引发异常。

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

运行时注意: B::setValue() 的声明应该与 B.php 行中的 A::setValue(Type $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()

4

1 回答 1

1

你已经工作的东西,不需要instanceof你做的检查。您可以在参数类型提示中声明类型。

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

在适当的多态性中,这应该有效:

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

$obj->setValue(new Type);

用你正在尝试做的事情是行不通的。

于 2012-12-13T13:34:54.527 回答