嘗試以下操作:
包inputabstraction
abstract class Point[T](n:String){
def value: T
val name = n
}
case class Input[T](n:String, value:T) extends Point[T](n)
object testTypedCaseClass{
def test(){
val foo = Input("foo", "bar")
println(foo)
}
}
一個簡單的應用,以檢查它的工作原理:
import inputabstraction._
object TestApp extends Application{
testTypedCaseClass.test()
}
說明
您所做的第一個錯誤是case class Input[Type](n:String) extends Point(n){
。 Point是一個類型化的類,因此當您使用extends Point(n)
調用超類的構造函數時,您需要指定Point
的類型。這是這樣完成的:extends Point[T](n)
,其中T是您計劃使用的類型。
第二個錯誤是您既定義和聲明值:T在這裏:var value: Type = _
。在這個聲明中,_
是一個值。它的值是Nothing
。 scala編譯器從此推斷出Point[T]
是Point[Nothing]
。因此,當您嘗試將其設置爲setValue
方法正文中的類型時,必須將其設置爲Nothing
,這可能不是您想要的。如果您嘗試將其設置爲除Nothing
之外的任何內容,則會從上面得到類型不匹配,因爲由於您使用了_
,所以鍵入的值爲Nothing
。
第三個錯誤是使用var
而不是val
或def
。val
和def
可以互換覆蓋,這意味着亞型可與val
或def
覆蓋,和Scala編譯器會看着辦吧你。它是用來定義瓦爾斯如使用抽象類和特質def
功能的最佳做法,因爲亞型構造函數初始化順序是一件很困難的事情得到正確的(沒有爲編譯器如何確定如何從它的超類型構造一個類的algorithm )。 TL#DR ===在超類型中使用def。大小寫類參數會自動生成val
字段,由於您要擴展Point,因此將創建val值字段,該字段將覆蓋Point[T]
中的def值字段。
你可以擺脫這一切Type
||因爲類型推斷和Point
是抽象的事實,因此可以通過val擴展值。
做的依賴注入這樣的首選方式是cake pattern,但這個例子我已經提供了您的用例的作品。
這個答案不正確。僅僅添加類型的情況下類,當他試圖用'setValue'與除'Nothing'任何其它類型不會編譯: '抽象類Point [T](n爲字符串){ VAR值:T = _ VAL名稱=正 } 情況下類輸入[T](n爲字符串)延伸點[T](N){ DEF的setValue(VA:T)=值= VA } 對象testTypedCaseClass { DEF測試(){ VAL富=輸入( 「foo」 的) foo.setValue( 「條」) 的println(富) } }' RESU lts在: 'type mismatch;' 編譯時 這是因爲他在'Point [T]'中聲明的值是'Nothing'。 – 2012-04-23 21:02:37
不能相信我犯了這個簡單的錯誤。事實上,這是錯誤的一部分,但如果我改變了這一點,並保留其餘部分,它給了我同樣的錯誤。 – 2012-04-23 21:10:59
作爲@JackViers提到的,使用默認值,再加上一些通用的類型爲價值是相當混亂,這將實現默認值加上一個setter這是不是在同一層上,但我不把所有的代碼,所以我建議一個簡單的「補丁」。請毫不猶豫地在您的問題中提供更多細節。 – 2012-04-23 21:14:00