可能是斯卡拉大師的一個簡單的。我正在閱讀類型約束的約束,並想知道我是否錯過了一些東西,因爲我看到一個稍微意外的行爲。比方說,我們有三種類型的A,B,C在這樣的層次,爲此,我們正在與類型界限的實驗:斯卡拉類型邊界行爲(方法vs類)
class A {
}
class B extends A {
}
class C extends B {
}
class MyList1 { // T super B
def add[T >: B](a: T): Unit = {}
}
class MyList2 { // T extends B
def add[T <: B](a: T): Unit = {}
}
class MyList3[T >: B] { // T super B
def add(a: T): Unit = {}
}
class MyList4[T <: B] { // T extends B
def add(a: T): Unit = {}
}
object BoundsClass {
def main(args: Array[String]) {
val l1 = new MyList1
l1.add(new A)
l1.add(new B)
l1.add(new C) // why is this allowed??
val l2 = new MyList2
// l2.add(new A) // not allowed (OK)
l2.add(new B)
l2.add(new C)
val l3a = new MyList3[A]
val l3b = new MyList3[B]
// val l3c = new MyList3[C] // not allowed (OK)
// val l4a = new MyList4[A] // not allowed (OK)
val l4b = new MyList4[B]
val l4c = new MyList4[C]
}
}
的集合表現爲預期所有除一個案例,看看l1.add (新C);不會導致編譯錯誤。爲什麼這是允許的?
謝謝!
如果試過這兩個:「val c1:A = new C」和「val c2:C = new C」。我認爲第二個不應該(因爲集合「l3c」)因爲約束是「T是B的超類型」,但是c2顯然是這裏的子類型嗎?但是再次沒有錯誤...... – Nikolaos
'c2'是'C'的*實例*,由於繼承是如何工作的,它也是'B'(和'A')的一個實例,所以它不是錯誤。 – Dylan