2012-01-07 26 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

相關問題