次のことを試してください。
パッケージ入力の抽象化
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 は、使用する予定のタイプです。
2 番目のエラーは、 value:T here: の定義と宣言の両方を行っていることですvar value: Type = _
。このステートメントで_
は、 は値です。その値はNothing
です。scala コンパイラは、これから を推論しPoint[T]
ますPoint[Nothing]
。したがって、メソッドの本体で型に設定しようとすると、 に設定setValue
する必要がありますがNothing
、これはおそらく望んでいるものではありません。以外の値に設定しようとするとNothing
、上記の型の不一致が発生Nothing
します_
。
3 番目の間違いは、 orvar
の代わりに使用しています。 とは交換可能にオーバーライドできます。つまり、サブタイプは または のいずれかでオーバーライドでき、scala コンパイラがそれを見つけ出します。サブタイプ コンストラクターの初期化順序を正しく設定するのは非常に難しいため、vals を抽象クラスとトレイトで使用する関数として定義することをお勧めします(コンパイラーがそのスーパータイプからクラスを構築する方法を決定する方法に関するアルゴリズムがあります)。 . TL#DR === スーパータイプで def を使用します。ケース クラス パラメータは自動的に生成されるフィールドであり、Point を拡張しているため、 の def 値フィールドをオーバーライドする val 値フィールドが作成されます。val
def
val
def
val
def
def
val
Point[T]
||このすべてを回避できますType
|| T
型推論と抽象であるという事実のため、Scala でのPoint
抽象化は、val を介して値を拡張可能にします。
このような依存性注入を行う好ましい方法はcake patternですが、私が提供したこの例はあなたのユースケースに適しています。