而且我相信这是因为asInstanceOf
似乎this
隐含使用的调用。
Scala 中的每个类Any
都继承了特殊的方法asInstanceOf
,等等。我不会说它是隐式发生的——只是你正在调用该类的一个成员方法,它是在自己调用它。就像你写的一样def moo = greet
。
此外,任何时候使用asInstanceOf
,都是在要求编译器对自己撒谎并继续运行。这通常会导致ClassCastException
. 在这种情况下,这是因为您试图将实例A
转换为Foo
. 这永远不会奏效。在非常具体的情况下,您尝试将单例类型传递给的Coo.type
实例,然后A
创建. 虽然还有许多其他原因导致这不起作用,但其中一个原因是您无法创建单例类型的第二个实例——之所以这样称呼它是有原因的。Coo.type
更一般地说,您不知道可以简单地构造给定类型的对象。类型没有构造函数,类有。
这可能是作为简化示例的副作用,但您关心的是创建一个A
具有某种类型参数的实例,而无需将其传递给实际对象,但您关心的对象已经存在。那么为什么不通过它们呢?
class A[Fooer <: Foo](f: Fooer) {
def moo = f.greet
}
做到这一点的唯一其他方法是提供Fooer
可以构建的证据。但是,没有类型约束来证明某事物是可构造的类。您可以做的是需要一个Class
元对象:
class A[Fooer <: Foo](clazz: Class[Fooer]) {
def moo = clazz.newInstance.greet
}
然而,这很粗糙。首先,它不适用于上面的单例类型(因为它们不能再次构造)。其次,我们只能newInstance
在没有构造函数参数提供时调用,并且没有办法强制执行。
所以虽然这会起作用:
scala> class Bar extends Foo { def greet = print("Bar") }
scala> new A(classOf[Bar]).moo
Bar
以下不会:
scala> class Baz(i: Int) extends Foo { def greet = println("Baz") }
defined class Baz
scala> new A(classOf[Baz]).moo
java.lang.InstantiationException: Baz
scala> new A(classOf[Coo.type]).moo
<console>:14: error: class type required but Coo.type found
new A(classOf[Coo.type]).moo
^
或者,您可以使用允许您一致地构建 的实例的类型类Foo
,但这需要为每个子类创建一个。例如:
trait FooBuilder[A] {
def build(): A
}
implicit object BarBuilder extends FooBuilder[Bar] {
def build() = new Bar
}
class A[Fooer <: Foo](implicit fb: FooBuilder[Fooer]) {
def moo = fb.build().greet
}