假设,我们有:
class B
class A extends B
trait T
然后它成立:
val a: A with T = new A with T
a.isInstanceOf[B] // result is true !
是不是说isInstanceOf
方法检查,如果在子类型关系中至少有一种类型(不是所有类型)与右侧匹配?
初看起来,我认为类型A with T
的值不能是B
的子类型,因为A
和 T
是不是B
的两种子类型。但它是A
或 T
是B
的子类型 - 是吗?
答案 0 :(得分:35)
isInstanceOf
查看继承链中是否有相应的条目。 A with T
链包含A
,B
和T
,因此a.isInstanceOf[B]
必须为真。
编辑:
实际上生成的字节代码调用javas instanceof
,因此在java中它将是a instanceof B
。像a.isInstanceOf[A with T]
这样的一个更复杂的调用将是(a instanceof A) && (a instanceof T)
。
答案 1 :(得分:11)
初看起来,我认为带有T的类型A的值不能是a B的亚型
这里有两个误解。首先,实例的静态类型与isInstanceOf
的结果有任何关系:没有。需要明确的是,在a.isInstanceOf[B]
执行时,a
类型为A with T
的事实与无关。
方法isInstanceOf
由JVM在字节码级别实现。它查看每个实例承载的类信息,并检查B
其中一个类(实例本身及其祖先的类)或其中一个已实现的接口。这就是“is-a”关系:“a是B”。
从技术上讲,isInstanceOf
是Java反思的一部分,它被称为instanceof
。
第二个误解是继承可以某种方式删除父类型。永远不会发生:继承只添加类型,永远不会删除它们。类型A with T
是A
,B
,T
,AnyVal
和Any
。因此,即使isInstanceOf
确实查看类型A with T
,它仍然会返回true。