PHP 类型提示无法与接口和抽象类相处?

发布于 2024-10-09 23:26:40 字数 841 浏览 4 评论 0原文

我认为在代码示例中看到问题比首先编写问题要容易得多。这是我的 php 代码:

<?php

interface AnInterface
{
        public function method();
}    

class AClass implements AnInterface
{
        public function method()
        {
                echo __METHOD__;
        }
}    

abstract class AnAbstractClass
{
        abstract public function method( AnInterface $Object );
}

class ConcreteClass extends AnAbstractClass
{
        public function method( AClass $Object )
        {
                $Object->method();
        }
}

$Object1 = new ConcreteClass();
$Object2 = new AClass();

$Object1->method( $Object2 );

上面的代码导致以下错误:

致命错误:ConcreteClass::method() 的声明必须与 AnAbstractClass::method() 的声明兼容

问题是 php 似乎无法将 AnAbstractClass::method 和 ConcreteClass::method 的签名识别为兼容。我做错了什么吗?谢谢!

I think it'll be much easier to see the problem in a code example than writing the question in the first place. Here is my php code:

<?php

interface AnInterface
{
        public function method();
}    

class AClass implements AnInterface
{
        public function method()
        {
                echo __METHOD__;
        }
}    

abstract class AnAbstractClass
{
        abstract public function method( AnInterface $Object );
}

class ConcreteClass extends AnAbstractClass
{
        public function method( AClass $Object )
        {
                $Object->method();
        }
}

$Object1 = new ConcreteClass();
$Object2 = new AClass();

$Object1->method( $Object2 );

The above code causes the following error:

Fatal error: Declaration of ConcreteClass::method() must be compatible with that of AnAbstractClass::method()

The problem is that php doesn't seem to be recognizing the signatures of AnAbstractClass::method and ConcreteClass::method as compatible. Am I doing something wrong? Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

ゞ花落谁相伴 2024-10-16 23:26:40

php 似乎无法将 AnAbstractClass::methodConcreteClass::method 的签名识别为兼容。

PHP 是正确的,它们兼容。通过仅允许将 AClass(或其子级)的实例传递给 ConcreteClass::method,您就违反了 AnAbstractClass 提供的约定:它的任何子类都必须接受 AnInterface 作为其 method() 的参数。

如果您的示例有效,并且我有另一个类 BClass 实现 AnInterface,我们会遇到一种情况,根据 AnAbstractClassmethod () 应该接受 BClass 的实例,而根据 ConcreteClass ,它不应该接受。

更改 ConcreteClass::method 的签名以匹配 AnAbstractClass::method 的签名。

php doesn't seem to be recognizing the signatures of AnAbstractClass::method and ConcreteClass::method as compatible.

PHP is correct, they're not compatible. By allowing only instances of AClass (or its children) to be passed to ConcreteClass::method, you're breaking the contract that AnAbstractClass provides: Any of its subclasses must accept AnInterface as an argument to its method().

If your example worked, and I had another class BClass implementing AnInterface, we'd have a situation where according to AnAbstractClass, method() should accept instances of BClass, while according to ConcreteClass, it shouldn't.

Change your signature for ConcreteClass::method to match that of AnAbstractClass::method.

两相知 2024-10-16 23:26:40

下面是一个示例,说明为什么不允许这样做:

<?php
class BClass implements AnInterface { }

function moo(AnAbstractClass $abstract)
{
    $b = new BClass();
    $abstract->method($b);
}

这将是一个有效的代码,但如果您将 ConcreteClass 传递给 moo,它会失败,因为它的方法 ConcreteClass::method< /code> 不允许 BClass

虽然很复杂,但是如果你看个例子就更容易理解了。

Here's an example that shows, why this is not allowed:

<?php
class BClass implements AnInterface { }

function moo(AnAbstractClass $abstract)
{
    $b = new BClass();
    $abstract->method($b);
}

This would be a valid code, but it would fail, if you pass a ConcreteClass to moo, because its method ConcreteClass::method does not allow BClass.

It is complicated, but it is easier to understand, if you see an example.

醉态萌生 2024-10-16 23:26:40

不会计算。昨天我们进行了同样的讨论:
参数类型可以专门用于 PHP

所有派生的类必须以相同的方式实现方法签名。

理想情况下,这是在运行时检查的事情。但在 PHP 中,解析器会这样做。 (作为补偿,PHP 在解析时不会检查私有/受保护的属性访问,而是让其在运行时爆炸。)

如果您想强制执行更严格的类型,我建议:

 assert( is_a($Object, "AClass") );

Does not compute. We had the same discussion yesterday:
Can parameter types be specialized in PHP

All your derived classes must implement the method signatures identically.

This is something that would ideally be checked at runtime. But in PHP the parser does. (To compensate, PHP does not check private/protected attribute access at parsing time, but let that one rather blow up at runtime.)

If you want to enforce a more stringent type, I would advise:

 assert( is_a($Object, "AClass") );
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文