【问题标题】:Why is overriding an already implemented abstract type not possible?为什么不可能覆盖已经实现的抽象类型?
【发布时间】:2012-01-08 02:11:07
【问题描述】:

给定以下代码:

class A {

  class B

  type C <: B

  trait D

}

class E extends A {

  type C = B

}

class F extends E {

  override type C = B with D

}

为什么 Eclipse Indigo IDE 中的 Scala IDE 演示编译器会报错并显示错误消息 overriding type C in class E, which equals F.this.B; C 型有不兼容的类型

毕竟类“B”只是“修改”了特征“D”,因此两个类型定义具有相同的基本类型,即“B”。因此兼容的类型定义。

下面的代码有效。我认为类型赋值的规则类似于变量赋值,例如:

class Foo

trait Bar

val a: Foo =  new Foo

val fooWithBar: Foo = new Foo with Bar

我的理解有错吗?

【问题讨论】:

  • Foo with Bar 是 Foo 的子类型。这不是问题所在。固定类型成员时,您不能重新定义它,即使是子类型也是如此。如果你有类 Bar 扩展 Foo,你也不能将类型成员从 Foo 重新定义为 Bar。

标签: scala overriding abstract-type


【解决方案1】:

它们不兼容,类型 C 可能用于逆变位置

class E extends A {
  type C = B
  def f(c: C)
}


class F extends E {
  override type C = B with D 
  def f(c: ???)
}

补充 给定e: E,您可以拨打e.f(new B)。如果eval e = new F 会怎样?

【讨论】:

  • 只要覆盖的类型“C”被进一步限制并保持其基本类型“B”,为什么这个星座不健全。如果方法“f”接受“B”,为什么它不应该接受其子类,根据重新定义“B with D”?
  • 如果方法接受 B,当然它必须接受子类型。问题是 F 的实例需要 B 和 D,因此不再接受简单的 B。E 的子类型必须接受 f 中的 B。它当然会接受子类型。它不能要求参数是子类型。
  • 我不确定这是不是正确的反例。原因如下:(对不起,无视,我试图在手机上点击取消,但它却被发布了......)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多