【问题标题】:Cannot Declare Child Class Method declared in Interface on Super Class无法在超类的接口中声明子类方法
【发布时间】:2011-05-26 23:52:19
【问题描述】:

这应该是一个非常简单的类和接口问题,但请耐心等待我的示例。

在 Propel ORM 库中,所有数据库表都被抽象为称为 BaseTablename 的类。与数据库交互的各种方法在基本对象中定义。然后该库还会生成以表命名的类,例如Tablename,对于覆盖基方法和添加自定义方法非常方便。

我只是试图覆盖默认的delete() 方法,以便能够删除一些依赖数据。但是当我声明覆盖方法时,我收到以下错误:

致命错误:Tablename::delete() 的声明必须与 Persistent::delete() 的声明兼容

那么,考虑到以下基本定义,为什么我不能覆盖delete() 方法?

/**
 * Part of the Propel library
 */
interface Persistent {
    public function delete (PropelPDO $con = null);
}

/**
 * Generated by Propel
 */
class BaseTablename extends BaseObject implements Persistent {
    public function delete (PropelPDO $con = null) {
        doesImportantStuff();
    }
}

/**
 * Skeleton class is generated by Propel
 */
class Tablename extends BaseTablename {
    /**
     * MY OWN BEAUTIFUL [BUT BROKEN] CODE
     */
    public function delete (PropelPDO $con = null) {
        doMyOwnStuff();

        // Added this 2011-05-30 -- As it happens, this IS the Problem!
        // I needed to add the $con parameter to the call to preserve
        // the "chain of compatibility", so to speak.
        parent::delete();
    }
}

更新:我添加了我的 parent::delete() 调用,但我未能将其包含在我的原始示例代码中。这真的会让一切变得不同。对不起,非常感谢那些确认工作代码的人

答案是我需要在所有声明和调用中保留参数。我的重载函数应该是这样的:

    public function delete (PropelPDO $con = null) {
        doMyOwnStuff();

        parent::delete($con);
    }

【问题讨论】:

  • 此代码可以正常工作。确保服务器上的文件与本地副本同步。
  • 请查看我对问题所做的更改。我不想自己回答这个问题,因为是我的错误导致这个问题可以回答;所以在 Alrik 和 OZ_ 之间,无论谁先发布正确答案,我都会授予 Accept 给。不过,我仍然非常感谢你们确认其他工作代码 - 这让我更加确信这实际上是唯一的问题。
  • 把答案写成答案。不要将其编辑到问题中。
  • 如前所述,我正在等待原始响应者之一这样做。当几个人付出巨大的努力来回答我的问题时,我不会把功劳归于我,但事实证明这是无法解决的。
  • this IS the Problem! - 不,这也不是问题的原因。方法声明错误。在以下情况下声明不兼容: a) 方法在类中声明为静态,在接口中声明为动态(正常),反之亦然; b) 当接口和类中的名称、参数数量(甚至是可选的)或参数类型不同时。

标签: php inheritance interface propel overloading


【解决方案1】:

此代码有效。问题必须在服务器副本或 PHP 版本中。 (我已经在 PHP 版本 5.3.3-7+squeeze1 上运行测试没有问题)

【讨论】:

  • Alrik,谢谢。请参阅我修改后的问题和附加的评论。
  • 我刚刚将您的答案标记为已接受,因为您是第一个回答准确答案的人。由于缺少信息,最初描述的实际问题无法解决。真正的答案是我需要确保函数签名与原始声明保持一致,包括从我的子类实际调用方法时。
【解决方案2】:

我已经运行了另一个简单的测试。使用您的代码,但有两个回声,它可以正常工作。就像在 C 中一样,在这种情况下,接口充当原型,正如您所说,它需要在它实现的类上具有相同的参数和可见性。

【讨论】:

    猜你喜欢
    • 2014-02-02
    • 2015-07-10
    • 1970-01-01
    • 2013-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-24
    • 2011-06-16
    相关资源
    最近更新 更多