【问题标题】:Multiple Inheritance in Ruby, Java etcRuby,Java等中的多重继承
【发布时间】:2011-09-21 18:32:01
【问题描述】:

听起来可能很傻,但是如果每个类都隐含地扩展了Object类,并且允许再扩展一个类,那怎么不是多重继承呢?从用户的角度来看,可能会说他们不支持多重继承,因为不允许用户扩展多个类。但是,这些语言似乎具有对多重继承的内部支持,这可能是为了保持简单而不向用户公开。我说得有道理吗?

注意:我不是在争论或反对支持多重继承。只是想澄清一些想法。

【问题讨论】:

  • 一个类除了 Object 之外没有扩展“一个类”。如果不指定父级,则默认父级为 Object。
  • 你的评论是正确的,我现在觉得很愚蠢。但这不会是第一次或最后一次。因此,每个类都不是隐式扩展对象,而是仅在没有指定父对象时才扩展。但是每个类都可以访问 Object 的属性,因为它的层次结构以一种或另一种方式包括 Object 作为根。所以这些语言没有对多重继承的内部或外部支持。说得通。谢谢。

标签: java ruby multiple-inheritance


【解决方案1】:

典型的 OO 系统支持一个(具有任意长度)派生类。从任何一个子类的角度来看,父类形成了一个返回 Object 的链。立即查看所有类,我们看到类层次结构实际上是一棵树,在 Object 下方有一个非常宽的扇出。

典型的是允许树上的两个分支在具有直接多个超类的类中再次合并,这就是“多重继承”的意思.

你是正确的,它在英语意义上可能是“多个”,但在 OO 意义上不是“多个”,最终能够将单个对象传递给多个接口,每个接口都需要一个不相关的父对象类。

解决此限制的方法也很典型,这就是为什么您在 Java 中具有接口并在 Ruby 中包含(“mixin”)模块的原因。

【讨论】:

  • 现在我需要开始思考 :)
  • +1,说得好。一个小问题:“它真的是一棵树”是一种从类模型到类层次结构的奇怪转移,它缺少一个先行词,并且与前一句所暗示的不同。
  • +1。我们可以通过组合来实现多重继承的目标,这正是Java和Ruby正在做的事情。我的问题更多是关于语言是否支持多重继承,但不向用户公开。 David Nehme 的评论帮助我找出了思维过程中的缺陷。
  • @Andy - 好点,我已经更新它以更优雅地在主题之间过渡。
【解决方案2】:

您描述的情况只是纯继承,它与多重继承没有任何共同之处。例如,在 Java 中,Integer 继承自 NumberNumber 继承自 Object

具有多重继承的语言的标准示例是 C++

class A { };
class B { };
class C { };
class X : public A, private B, public C { };

而在 Java 中我们有

class A { }
class B extends A { }
class C extends B { }
class X extends C { }

就多重继承而言,Ruby 类似于 Java(Ruby 中的类只能有一个祖先)。然而,Ruby 提供了不同的机制来“充当”多重继承,即模块

# class XX inherits from CC
class AA 
end
class BB < AA
end
class CC < BB
end
class XX < CC
end

# class X mixin A,B,C modules
module A end
module B end
module C end
class X 
    include A
    include B
    include C
end

在 Ruby(类似于 Java)中,类 AA 具有默认祖先(继承链取决于 Ruby 版本)

X.ancestors
[X, C, B, A, Object, Kernel, BasicObject]
XX.ancestors
[XX, CC, BB, AA, Object, Kernel, BasicObject]

【讨论】:

  • 我喜欢您的回答,其中包含清晰的示例,并为此 +1。但是,我不确定您对“您描述的情况只是纯继承,它与多重继承没有任何共同之处”是否正确。在 Java 和 Ruby 中,每一层的祖先只能是一个类,也就是常规继承。我一直认为并且仍然认为多重继承意味着能够同时从多个类继承。我们中的一个人可能会对这里的术语感到困惑,我会让其他人对此进行权衡。我确实在 David Nehme 的评论中找到了我原来问题的答案。
  • @Srini K,在某种程度上,使用 mixins 就像“同时使用多个类”。在 ruby​​ 中,与 Java 不同的是,最基本的构建块实际上是 Module,而不是 Class(类继承 Module)。当你使用 mixins 时,虽然效果可能“感觉像”多重继承,但 ruby​​ 实际上只是按照模块包含的顺序将每个模块插入到继承链中。
【解决方案3】:

不同之处在于“真正的”多重继承允许您从不同类树中的不同类继承。如果您的子类继承的两个类具有相似的属性或方法,那么问题就变成了,那么您必须处理子类中的冲突。

在 Java 等不允许多重继承的语言中,相同的成员会被子类中的成员简单地覆盖。

总之,即使您的类型层次结构中可以有许多类,您也只会有每个成员的一个版本,因为每个子成员都会用自己的覆盖父成员。

【讨论】:

    【解决方案4】:

    正如您所指出的,Java 中的所有引用类型都是 java.lang.Object

    定义自定义类型的开发人员可以使用一种实现进行扩展。您可以选择实现多个接口,但这些接口不附带任何实现。开发者必须自己添加。

    因此,当您说 Java 中的自定义类型从 java.lang.Object 和扩展的超类接收实现时,您可能完全正确,但它被认为是实现的单一继承,因为开发人员只能扩展一个实现类。

    你在争论语义。您不能在 Java 中扩展多个实现。

    但是你可以实现多个接口。

    【讨论】:

      猜你喜欢
      • 2012-05-02
      • 1970-01-01
      • 1970-01-01
      • 2013-02-20
      • 2014-03-16
      • 2010-11-08
      • 2015-11-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多