定义两个类:
class A { def method1 = this }
class B extends A { def method2 = this }
val b = new B
然后我查看b.method1的类型:
scala> b.method1.getClass
res29: Class[_ <: A] = class B
这种情况下无法调用b.method1.method2
scala> b.method1.method2
<console>:11: error: value method2 is not a member of A
b.method1.method2
将A和B两个类的定义加上this.type:
class A { def method1: this.type = this }
class B extends A { def method2: this.type = this }
val b = new B
再查看b.method1的类型:
scala> b.method1.getClass
res31: Class[_ <: B] = class B
这时可以调用b.method1.method2方法:
scala> b.method1.method2
res32: b.type = B@4ff3ac
我的问题是:res29: Class[_ <: A] = class B
和 res31: Class[_ <: B] = class B
这样的类型格式是什么意思?看上去觉得这两个都是B的类,为什么前一个不能调用B的方法呢?
res29: Class[_ <: A] = class B
的意思是结果参数 res29 的类型是 Class[_ <: A],值为 class B。 _ <: A 表示任意 A 的子类型。
对于 b.method1.method2 不能调用的原因可以参看一下:http://scalada.blogspot.com/2008/02/thistype-for-chaining-method-calls.html
我估计你的问题也是从这篇帖子来吧。还可以看看这篇问题:
http://stackoverflow.com/questions/4313139/how-to-use-scalas-this-typing-abstract-types-etc-to-implement-a-self-type
主要原因就是:
class A { def method1 = this }
中 method1 返回类型为 A,没有写出来但编译器会推断为 A。确认方法是自己在这里填上 : A 看编译器报错不。
所以 b.method1 返回的是 A 类型的对象,A 类型中没有 method2。
而带上 this.type 后:
class A { def method1: this.type = this }
this.type 是 method1 的返回值,这个返回值很特殊,得在运行期才会真正计算出具体类型,所以当对象实际类型是 B 的时候,调用 b.method1 返回的还是子类 B 类型,而不是 A 类型。这个就是 this type 的用途,是 scala 为了满足这类需求专门设计的关键字。