重写接口方法PHP


Override interface method PHP

我有以下代码

class Model_MyAbstractClass {
}
class Model_MyClass extends Model_MyAbstractClass {
}
interface doStuff {
    function update(Model_MyAbstractClass $model);
}
class Mapper_MyClass implements doStuff{
     function update(Model_MyClass $model){
      }
}

那么,为什么这在PHP中不起作用呢?Model_MyClass仍然是Model_MyAbstractClass。我有5个类(也许我会有更多)使用类似的方法。完全不同的是,每个映射器都有一些模型,它们都扩展了model_MyAbstractClass
如果真的没有办法做到这一点,那么剩下的解决方案就是:为它们中的每一个创建一个接口,唯一的区别是params(根本不是DRY)
如果Model_MyAbstractClass是所需Model_MyClass的实例,请检查每个函数,并抛出一个错误——这似乎是一个愚蠢的策略,因为我应该明确要求所需类型的参数。

这是正常的,不起作用。

您的接口假设,您可以将任何Model_MyAbstractClass传递到此函数:

function update(Model_MyAbstractClass $model);

在这里,您期望只有Model_MyClass:

class Mapper_MyClass implements doStuff{
     function update(Model_MyClass $model){    
     }
}

当然,Model_MyClassModel_MyAbstractClass的一个实例。但是接口会假设,您也可以传递从Model_MyAbstractClass扩展而来的类Model_SomeOtherClass

摘要:您应该能够处理ANYModel_MyAbstractClassNOT ONLYModel_MyClass


您可能需要的:

class Mapper_MyClass implements doStuff
{
    function update(Model_MyAbstractClass $model)
    {
        //Do stuff on Model_MyAbstractClass
        //...
        if ($model instanceof Model_MyClass) {
            //Do additional stuff on Model_MyClass
            //...
        }
    }
}

也许你遇到了和我一样的问题,通过C#Java可以很容易地解决。对我来说,我想要一个Generic基类。这样的东西:

abstract class Foo<T> {
    function update(T $model)
}
class Bar extends Foo<Model_MyClass> {
}

这是目前普通PHP无法实现的,但Facebook的黑客让它成为可能。问题是,这不是我的选择,但也许对你来说。我已经用如上所述的instanceof的使用方式来完成了。

您的问题与PHP无关,更多的是对OOP概念中接口工作方式的误解。

根据您的代码,接口doStuff有一个以Model_MyAbstractClass为参数的方法,这意味着参数实例将始终显示为Model_MyAbstractClass,而不是其他任何内容,无论给定实例是否是Model_MyAbstractClass的实例,就像您的示例中一样。

在OOP语言(如Java)中,您将收到如下错误:

The method update(Model_MyAbstractClass) of type Mapper_MyClass must override or implement a supertype method

但是,在PHP中您可以执行instanceof检查,在OOP语言中您可以进行castModel_MyClass