如何在父類中定義回傳型別以使其與子實體類匹配?
在下面的示例中,需要定義 echo 函式,以便它回傳呼叫 this 的子類的物件。
trait A[T] {
def echo(a: T): T
}
class B extends A[B] {
override def echo(x: B):B = x
}
class C extends B {
def repeat(x: B): B = echo(x)
}
val b = new B()
val c = new C()
// Fails with error value repeat is not a member of B
c.repeat(b).repeat(b)
// Compilation error
// Found: B
// Required: D
class D extends B {
def repeat(x: B): D = echo(x)
}
}
uj5u.com熱心網友回復:
你到底想做什么?
如果您跟蹤您的呼叫鏈,您會看到c.repeat(b)回傳的實體b:B顯然沒有repeat在C.
換句話說,在您的代碼中,b.echo(x:B)回傳x,而不是this!
也許你想this從C.repeat? 這應該有效:
class C extends B {
def repeat(x: B): C = {
echo(x)
this
}
}
val b = new B()
val c = new C()
c.repeat(b).repeat(b)
uj5u.com熱心網友回復:
正如@Aivean 所提到的,您的方法repeat是在類上定義的,C并回傳其父類的一個實體,該實體B沒有該repeat方法。
所以你不能像這樣呼叫重復兩次:
val tmpB = c.repeat(b) // tmpB is an instance of B
tmpB.repeat(b) // fail cuz B has no "repeat" method
就是這樣。
現在回答主要問題:“如何使父類回傳可以匹配子型別的型別?”
與您對 trait A 所做的相同,但對其引數型別添加約束,以便 T 必須是 A:
trait A[T<:A[T]]
class B extends A[B]
在這個很好的答案中閱讀更多關于“F-bounded polymorphism”的資訊:https : //stackoverflow.com/a/21699765/1206998
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/344792.html
上一篇:OpenCV獲取矩陣的形狀
