【问题标题】:Why are Super-class and Sub-class reversed?为什么超类和子类颠倒了?
【发布时间】:2010-02-21 00:38:37
【问题描述】:

在集合论中,如果集合包含原始集合中的所有内容,甚至可能更多,它就是超集。然而,一个子集并不包含初始集合的所有内容。

考虑到这一点,在大多数面向对象的编程语言中(我认为是 Objective-C,但我知道 Java 和其他语言也是如此),父类称为 super 类,并且任何类从 super 继承的称为 subclass。

这不是倒退吗?子类从其超类继承所有实例变量和方法,因此它“包含”来自父类的所有内容,以及添加到子类中的所有内容。这只是命名错误还是故意的,如果是,为什么?

【问题讨论】:

  • 在说一个或另一个之前我总是要检查自己

标签: language-agnostic oop programming-languages


【解决方案1】:

超类定义了一个具有更大组可能值作为成员的类。子类限制了可以成为其类一部分的项目,因此它定义了一个较小的可能的成员集。

超类的可能成员集是该超类的子类的可能成员集的超集。

【讨论】:

  • jbrennan:你不应该把一个类看作是它的一组属性。您应该将其视为所有可能实例的集合。那么这将是有道理的。就像数学中 Z 是 N 的严格超集一样,因为所有自然数都是整数,但并非所有整数都是自然数,Object 是 Java 中 String 的超类,因为所有字符串都是对象,但并非所有对象都是字符串。
  • @jbrennan:您正在考虑类的 attributes,不可能是那种类型的 values(在集合术语中,集合的成员类定义的值)。所有可能的Shape 值的集合包含一些是圆形的值和一些是正方形的值,但Circle 和Square 可能是具有比一般Shape 更小的可能成员集合的类。 (请记住,我使用术语“成员”作为“值集的成员”而不是编程术语“类成员”。)
  • 虽然这是一个很好的解释,但我觉得这是从空中摘下来的,以回顾性地解释为什么会这样:P。有没有参考的机会?
  • @Matt - 我也有这种感觉!有趣的是他们会把SubClass extends SuperClass.
  • @Matt:这是直集理论 - 但它只与 实例 有关,而不是属性和方法。
【解决方案2】:

格雷格是正确的。有两件事需要考虑,这可能会更清楚:

  1. 就集合论而言,属性和方法与子/超关系无关:

    • 子类定义的属性和方法可能会超出其超类提供的属性和方法(事实上,它们经常这样做),但子类的实例仍然是超类
    • 换句话说,sub/super 关系不是由属性和方法定义的,而是由类命名的实例级语义定义的
  2. 分类示例:

    • 所有人的集合大于所有程序员的集合
    • People 集合实际上是 Programmers 集合的超集
    • Programmers 集合是 People 集合的子集

所以在 OOP 术语中,People 将是一个超类,而 Programmer 将是一个子类。每个程序员都是一个人,但不是每个人都是程序员。因此超类和子类。 Programmer 类可能具有超越凡人的超能力这一事实并不会改变类关系 (is-a) 语义。

【讨论】:

  • 这个比其他的都好听
【解决方案3】:

格雷格的回答是正确的。下面举例说明:

你有一个基类 Base。您有两个派生类 DerivedA 和 DerivedB。 DerivedA 的每个实例也是 Base 的一个实例。同样,每个 DerivedB 也是一个 Base。但是,DerivedA 不是 DerivedB,反之亦然。所以,如果你要画出所有可能物体的宇宙维恩图,你会得到:

    ________________________
   /                        \
  /          Base            \
 /    ______        ______    \
|    /      \      /      \    |
|   /        \    /        \   |
|  | DerivedA |  | DerivedB |  |
|   \        /    \        /   |
|    \______/      \______/    |
 \                            /
  \                          /
   \________________________/

换句话说,DerivedA 对象集中的每个对象也在 Base 对象集中。 DerivedB 也是如此。所以 Base 确实是 DerivedA 和 DerivedB 的超集。因此,它是“超类”。

【讨论】:

    【解决方案4】:

    可能出于相同的原因,堆栈向下生长(底部在顶部),树向下生长(根在顶部)并且 2D 图形系统几乎总是第四象限(左上角的 0,0)。

    【讨论】:

    • 所以下一个问题是这个原因是什么:-)
    【解决方案5】:

    我回避了整个超/子类问题,将它们称为“派生”和“父”类。

    【讨论】:

    • 这可能只是更实用的方法
    【解决方案6】:

    子类拥有其父类的所有 [成员] [以及更多]。这不是倒退吗?

    这个问题出现在所有编程语言中,它总是让我头疼。 (尤其是子类型。)

    规则如下:

    • 当您考虑对象时,子类/子类/子类型有更多方法和成员。它可以在更多的上下文中使用。这似乎违反直觉。

    • 当您考虑上下文、接口或参数时,角色是相反的。例如,期望超类型/父/超类参数的方法可以接受比期望子类型参数的方法更多的参数。

    哪个在最上面完全取决于您是否认为对象是主要的,或者您是否认为期望对象的上下文是主要的。我研究这门学科将近 15 年,但我的直觉仍然出卖了我。

    如果一个类声明被认为是一个规范,那么更多个对象满足超类规范,满足子类规范通过更少的对象。我相信这就是命名的原因。 (如果你谈论子类型和超类型会更清楚一点——一个子类型包含的值比它的超类型少,因为子类型的每个值也是超类型的一个值,而超类型可能包含额外的值,这些值是不是子类型的成员。)

    我有没有提到整个话题让我头疼?

    【讨论】:

      【解决方案7】:

      是的,但是如果您将图表视为地形图,则子类的海拔高度高于超类。因此混乱。

      另一种看待这一点的方式是,超类类似于数字中的前导数字(为了使这成为编程语言友好的类比,我们将说是浮点数)。随着数字获得更多数字,每个新数字“继承”它之前的所有数字。类似地,随着子类获得更多方法,它会继承超类列表,按照它们被命名的顺序,在它之前。

      希望这会有所帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-11-21
        • 2012-09-05
        • 1970-01-01
        • 2012-06-18
        • 1970-01-01
        • 2017-03-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多