【问题标题】:Replication from multiple inheritance in Eiffel埃菲尔的多重继承复制
【发布时间】:2015-12-06 13:29:54
【问题描述】:

我很难理解多重继承与复制和多态性的相互作用。请考虑以下形成经典菱形图案的类。

deferred class A
  feature 
    a  deferred end
  end

deferred class B
  inherit A
    rename a as b end
  end

deferred class C
  inherit A
    rename a as c end
end

class D
  inherit 
    B
    C
    select c end
feature
  b do print("b") end
  c do print("c") end
end

如果我将 D 的实例附加到 C 类型的对象 ob_as_c,则 ob_as_c.c 会按预期打印“c”。但是,如果将实例附加到 B 类型的对象 ob_as_b,那么 ob_as_b.b 也会打印 print "c"。

这是预期的行为吗?显然,我希望ob_as_b.b 打印“b”。

【问题讨论】:

    标签: polymorphism multiple-inheritance eiffel


    【解决方案1】:

    仅描述 EiffelStudio 中可能与实际 ECMA 规范不同的实际行为。

    发生的情况是,如果没有 selectbc 都对应于 a 的一个版本。编译器会抱怨您有 2 个名称不同但版本相同的例程。通过使用“选择”,您正在修复错误并告诉编译器对于动态绑定,要使用的版本是 c,这与目标的类型无关,它基于运行时目标。

    【讨论】:

    • 感谢您的解释。不幸的是,这使得 Eiffel 的继承特性对我来说用处不大。
    • 关于 ECMA 规范:不是 8.16.11,“定义:动态绑定版本”,声明在我的示例中 ob_as_b.b 应该打印“b”,因为只有从 D 到的一致性路径B和D的特征b是B的继承特征b?只有当有两个或多个一致性路径时,select 子句才应该是相关的。
    【解决方案2】:

    (化妆品:拼写“延迟”。否则无法编译!)

    “select”只影响调用的语义,该调用的目标是用重复的祖先类型声明的实体,这里是 A,因为在这种情况下我们需要消除歧义。对于 B、C 或 D 类型的实体没有歧义,因此适用多态性和动态绑定的常规规则:对于同一个目标对象,实体(程序中的名称)是否声明为 B 类型无关紧要或 C。

    -- 伯特兰·迈耶

    【讨论】:

    • 您所描述的是我所期望的行为,我认为这在 ECMA 标准的 8.16.11 中有所规定。然而,这不是在 EiffelStudio 中发生的:在我的示例中,ob_as_b.b 的结果取决于 D 中的 select 子句,即使 B 不是 D 的重复祖先。(顺便说一句,我修复了令人尴尬的错字。)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-08
    • 2018-12-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多