我有以下代码
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_MyClass
是Model_MyAbstractClass
的一个实例。但是接口会假设,您也可以传递从Model_MyAbstractClass
扩展而来的类Model_SomeOtherClass
。
摘要:您应该能够处理ANYModel_MyAbstractClass
NOT 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语言中您可以进行cast
到Model_MyClass