あなたがしようとしているのはこれです:
scala> class A(val i: Int)
defined class A
scala> class B {
| def f[T](t: T) = println(t.toString)
| }
defined class B
scala> class C extends B {
| override def f[T <: A](a: T) = println(a.i * a.i)
| }
<console>:10: error: overriding method f in class B of type [T](t: T)Unit;
method f has incompatible type
override def f[T <: A](a: T) = println(a.i * a.i)
しかし、型システムが言うように、これは間違っています。ここでは、リスコフの置換原則に違反しています。
代わりにできることはT
、クラスレベルの型パラメーターまたは抽象型のメンバーを作成することです。次に、以下に示すように、サブクラスでそれを制約できます。
scala> class B {
| type T
| def f(t: T) = println(t.toString)
| }
defined class B
scala> class C extends B {
| type T = A
| override def f(a: T) = println(a.i * a.i)
| }
defined class C
scala> (new C).f(new A(11))
121
あなたはそれ以上の情報を提供していないので、これがあなたの特定のケースでうまくいくかどうかはわかりません。
編集:
物事を具体化する1つの方法は、型クラスを使用することです。コード:(これは予想よりも複雑であることが判明しました。)
scala> :paste
// Entering paste mode (ctrl-D to finish)
case class A(i: Int)
case object B
trait F[-A] {
def f(a: A): Unit
}
trait FLowPriorityImplicits {
implicit object FAny extends F[Any] {
def f(a: Any) = println(a.toString)
}
}
trait FImplicits extends FLowPriorityImplicits {
implicit object FA extends F[A] {
def f(a: A) = println(a.i * a.i)
}
}
object F extends FImplicits
def f[A](x: A)(implicit f: F[A]) = f.f(x)
// Exiting paste mode, now interpreting.
defined class A
defined module B
defined trait F
defined trait FLowPriorityImplicits
defined trait FImplicits
defined module F
f: [A](x: A)(implicit f: F[A])Unit
scala> f(B)
B
scala> f(A(2))
4