问题
scala> class A { type T <: String; def f(a: T) = println("foo")}
defined class A
scala> (new A).f("bar")
<console>:9: error: type mismatch;
found : java.lang.String("bar")
required: _1.T where val _1: A
(new A).f("bar")
^
Class A
has an abstract type T
, but is not an abstract class. Creating an object of A
(as shown) does not define type T
.
My first thought was, I am allowed to pass any type as T
which is a subclass of String, but I am not. So what type actually is T
in the object and what am I allowed to pass through ?
回答1:
As you say, T
in A
is abstract; therefore you won't find any value you can put into method f
, until you have a subtype of A
which actually fixes T
.
(new A { type T = String }).f("bar")
The idea is that the type can be successively refined:
trait Var[A] { def get: A; def set(v: A): Unit }
trait Sys {
type V[A] <: Var[A]
def swap[A](x: V[A], y: V[A]): Unit = {
val tmp = x.get
x.set(y.get)
y.set(tmp)
}
}
trait HistVar[A] extends Var[A] { def created: java.util.Date }
trait HistSys extends Sys {
type V[A] <: HistVar[A]
def newest[A](x: V[A], y: V[A]): A =
if (x.created after y.created) x.get else y.get
}
But of course you're question is good -- there is no reason why you would want a concrete instantiation of a class whose type parameter is not fixed. I can't think of a case where that makes sense. (Well of course, you could still have functionality that is accessible, if it does not involve type T
)
Further searching finds the following, quasi duplicate, SO question. You can find there a reference to a Scala ticket which outlines it as a 'feature' -- still doesn't show a case where this 'feature' is actually useful :)
来源:https://stackoverflow.com/questions/11274533/use-of-abstract-type-in-a-concrete-class