2012-01-07 55 views
8

考虑下面的代码:为什么重写已经实现的抽象类型是不可能的?

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 IDE英迪格内的Scala IDE的介绍编译器错误消息在E级,相当于F.this.B 压倒一切的C类抱怨; C型有不兼容型

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

下面的代码作品。我考虑的类型分配类同变量赋值的规则,如:

class Foo 

trait Bar 

val a: Foo = new Foo 

val fooWithBar: Foo = new Foo with Bar 

我的理解是错误的?

+1

Foo with Bar是Foo的子类型。这不是问题所在。不允许在修复类型成员时重新定义类型成员,即使是子类型也是如此。如果您将Bar添加到Foo中,则无法重新定义从Foo到Bar的类型成员。 – 2012-01-07 18:16:13

回答

13

它们互不兼容,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

+0

只要被覆盖的类型“C”被进一步限制并保持其基本类型“B”,为什么这个星座不适合。如果方法“f”接受“B”为什么不接受它的子类,按照重新定义“B with D”? – 2012-01-07 17:52:15

+3

如果方法接受B,肯定它必须接受子类型。问题是F的实例将需要B和D,所以不再接受简单的B。E的子类型必须接受f中的B.它当然会接受亚型。它不能要求参数是一个子类型。 – 2012-01-07 18:07:10

+0

我不确定这是否是正确的反例。原因如下:(抱歉,无视,我正尝试取消手机上的取消,但它已发布,而不是..) – 2012-01-08 14:21:10

相关问题