【问题标题】:Does overriding disqualifies a derived class from being a subtype of its base class?重写是否会取消派生类成为其基类的子类型的资格?
【发布时间】:2018-03-13 01:07:09
【问题描述】:

来自 Scott 的 Programming Language Pragmatics

派生类 D 具有其基类的所有成员(数据和子例程) C类。只要D不隐藏任何公开可见的 C 的成员,允许使用 D 类的对象是有意义的 在任何期望 C 类对象的上下文中:我们可能会做的任何事情 想对 C 类的对象做我们也可以对 C 类的对象做 D 类。换句话说,一个不隐藏任何内容的派生类 其基类的公开可见成员是该基类的子类型 类。

如果D 覆盖C 的公共方法,

  • D的覆盖方法是否隐藏C的覆盖方法,以及
  • 覆盖是否使D 无法成为C 的子类型?

什么可以让派生类隐藏基类的公共方法?

谢谢。

【问题讨论】:

    标签: oop inheritance programming-languages computer-science subtype


    【解决方案1】:

    重写是否使 D 无法成为 C 的子类型?

    这取决于。如果 D 中的方法违反了 C 中的方法定义的合同,那么是的,它将取消 D 成为子类型的资格。如果 D 方法支持相同的契约,那么它不支持。

    我建议您阅读 Liskov 替换原则。这是她在 1994 年写的原始文章。它的可读性很强。

    http://www.csnell.net/computerscience/Liskov_subtypes.pdf

    【讨论】:

    • 谢谢。 “如果 D 中的方法违反了 C 中的方法定义的合同”什么时候发生?怎么做才能保证“D方法支持同一个契约”?
    • 首先,定义合约。有时您可以使用断言来确保支持合同,但这取决于语言。
    【解决方案2】:

    D的覆盖方法是否隐藏C的覆盖方法

    不,覆盖与隐藏不同,因为您提供的是替代实现而不是现有实现,而不仅仅是在没有任何替代的情况下移除一个实现。

    大多数面向对象的语言不允许隐藏指定为覆盖的方法(C++ 的virtual、C# 的abstractvirtual)。有些语言根本不允许隐藏(Java)。这样做正是为了确保从 C 继承 D 模型“is-a”关系。

    覆盖是否使 D 无法成为 C 的子类型?

    不,它没有。

    【讨论】:

    • 请注意,subtyping 通常指的是 Liskov 的定义。斯科特在这里的定义似乎更宽松。但根据 Liskov 的说法,如果孩子违反了父母的合同,重写 可以 取消孩子成为其父母的子类型的资格。
    • @jaco。谢谢。 Liskov 和 Scott 对子类型的定义有什么区别?
    • @Tim,Liskov 将子类型定义为一种语义关系; Scott 似乎将其定义为仅仅是一种句法关系。
    • @jaco 谢谢。您在这里对子类型的语义关系和句法关系是什么意思?
    猜你喜欢
    • 1970-01-01
    • 2015-03-30
    • 2014-09-08
    相关资源
    最近更新 更多