scala的self type在某些情况下比较实用
需要注意的是:

self => 必须放在所有的属性之前

首先在内部类和外部类问题中应用,可以避免使用this产生二义性

代码示例



package main.scala.SelfTyleTest

/**
  * Created by postbird on 2016/9/13.
  */

class A{
    self =>
        val x=2
        def doSome():Unit={
            println(self.x+this.x)

            //此时 self可以代表类自身的引用避免使用this的时候的冲突
        }
}

class OutClass{
    outer =>
    //在内部类中使用self type能够很好地组织代码避免二义性
    // 有一个问题需要注意
    // outer =>  必须在OutClass的所有的属性的前面,如果将 val y:Int =2放在前面,则编译不通过
    val y:Int=2
    class InClass{
            val x:Int=1
            def doSome(): Unit ={
                println(outer.y+this.x)
            }
        }
}
object SelfTypeTest {
    def main(args: Array[String]) {
        new A().doSome
        //4
        val out=new OutClass()
        new out.InClass().doSome()
        //3
    }
}

当作为类型 也就是 self type的时候,使用案例如下

在声明一个类的时候强制性的必须混入另一个trait,则可以使用 self:TriatName => 

代码如下



package main.scala.SelfTyleTest

/**
  * Created by postbird on 2016/9/13.
  */
trait C{

}
trait B{
    self:C=>
}
//表示 如果要使用B 则必须混入C
//这个地方的self和之前内部类的使用是不一样的
class Test extends B with C{
    def doSome(): Unit ={
        println("Test class")
    }
}
object SelfTypeTest2 {
    def main(args: Array[String]) {
        new Test().doSome()
        //Test class
    }
}
//如果没有 with C 则报如下错误

//Error:(14, 20) illegal inheritance;
//self-type main.scala.SelfTyleTest.Test does not conform to main.scala.SelfTyleTest.B's selftype main.scala.SelfTyleTest.B with main.scala.SelfTyleTest.C
//class Test extends B{
//    ^