【发布时间】:2012-03-27 15:10:33
【问题描述】:
在用 PHP 构建 MVC 框架时,我遇到了一个可以使用 Java 样式泛型轻松解决的问题。一个抽象的 Controller 类可能看起来像这样:
abstract class Controller {
abstract public function addModel(Model $model);
可能存在类Controller的子类应该只接受Model的子类的情况。例如 ExtendedController 应该只接受 ReOrderableModel 到 addModel 方法,因为它提供了一个 ExtendedController 需要访问的 reOrder() 方法:
class ExtendedController extends Controller {
public function addModel(ReOrderableModel $model) {
在 PHP 中,继承的方法签名必须完全相同,因此类型提示不能更改为不同的类,即使该类继承了超类中提示的类类型。在java中我会简单地这样做:
abstract class Controller<T> {
abstract public addModel(T model);
class ExtendedController extends Controller<ReOrderableModel> {
public addModel(ReOrderableModel model) {
但是 PHP 中没有泛型支持。是否有任何解决方案仍然符合 OOP 原则?
编辑 我知道 PHP 根本不需要类型提示,但它可能是糟糕的 OOP。首先,从接口(方法签名)来看,应该接受什么样的对象并不明显。因此,如果另一个开发人员想要使用该方法,那么显然需要 X 类型的对象,而不必查看封装不良并违反信息隐藏原则的实现(方法体)。其次,因为没有类型安全,该方法可以接受任何无效变量,这意味着需要手动进行类型检查和异常抛出!
【问题讨论】:
-
在php中你可以传递任何你想要的类型对象而不必担心
-
我已经意识到这一点,但这可能是糟糕的 OOP。首先,从接口(方法签名)来看,应该接受什么样的对象并不明显。因此,如果另一个开发人员想要使用该方法,那么显然应该只使用 X 类型的对象,而不必查看封装不良并违反信息隐藏原则的实现(方法体)。其次,由于没有类型安全,该方法可以接受任何无效变量,这意味着需要手动进行类型检查和异常抛出。
-
这也是糟糕的 OOP,因为它违反了 LSP,您的 ExtendedController 专门化 控制器而不是扩展它。如果父级上的
addModel可以接受需要子类addModel只接受ReOderableModel的模型,这是非常糟糕的oop,并且违反了LSP。它也不会以任何明智的方式在 Java 中工作。这是 2 年前的,所以你现在可能已经知道了这一切…… -
请注意,有一个RFC for generics,目前正在草稿中。
标签: java php oop generics inheritance