【发布时间】:2019-08-03 17:11:13
【问题描述】:
TLDR:带有子对象参数的 add 方法与调用父类的实现不匹配。有没有解决的办法?
除非有更好的方法,否则我的计划是为 Collections 创建一个接口,如下所示:
interface Collection {
public function add( ValueObjects $obj ) : bool;
}
abstract class ValueObjects {}
class User extends ValueObjects {
}
然后我在用户值对象的具体集合上实现 Collection 接口。
class UserCollection implements Collection {
public function add( User $user ) : bool
{
return true;
}
}
这显然会引发Declaration should be compatible with Collection 的错误。有没有办法实现相同的结果以允许签名中的子对象?我尝试了抽象类,但没有结果。
如果我不必扩展抽象的 ValueObjects 类,那就更好了。
感谢您在 SO 社区分享您的知识。
PS...评论this question,装饰器和组合模式。我要么错过了它,要么我的问题有点不同。
【问题讨论】:
-
这就是为什么你不想这样做,即使它是可能的:你在某处得到一个
Collection对象,你想调用add方法。界面说你接受任何ValueObjects。所以你也是。但是你得到了一个UserCollection,它只接受它的一个子类型。Collection合约失效,你不能通过任何ValueObjects,只能通过User。你不能相信Collection,界面没有意义; en.wikipedia.org/wiki/Liskov_substitution_principle -
abstract ValueObjects类的意义何在?标记接口应该是接口;样板和实际扩展属于抽象,例如add,它很有用,除非被实现的合成器覆盖。 -
谢谢@Federkun,这很有道理。
-
标记接口是什么意思? @JaredFarrish 感谢您的解释
-
标记接口将类标记为类型,但没有实现细节。假设您只想将已知类型的无副作用值提供给方法。这太多样化了,无法猜测,而且超出了抽象性。使用
class User implements Valuable和interface Valuable {}标记该类,它没有具体表达这意味着什么,只是它通过了身份检查。它不能用一个类不实现副作用的接口来证明,所以通过将其标记为这样来强制开发“契约”它所做的事情。
标签: php design-patterns