天天看點

scala特質特質

特質

1.trait 關鍵字定義特質

** 特質類似java中的接口,功能卻比接口更加豐富,其實他更似一個類,唯一差別就是沒有帶參構造**
** trait 關鍵字定義特質 **
**  類,特質可以用 extends混入第一個特質,也可以再之後用with 混入更多特質 **
           
/**
  * 分别定義兩個特質
  */
trait Attribute {
  //可以存在一個抽象屬性
  val subject: String

  //也可以定義具體實作
  val state = "活着的"
  val name = "我是誰"
}

trait Motion {
  //抽象方法
  def move()

  //具體實作的方法。(帶有{},即表明該方法是一個已經實作了方法,不是抽象方法)
  def eat(s: String) {}
}
           

2.類中混入特質

/**
  * 一個具體的類可以使用關鍵字extends混入第一個特質,也可以再之後用with 混入更多特質,
  * 非抽象類混入特質,必須實作其抽象的方法或者屬性,此時可以不用關鍵字 override 修飾
  * 如果要覆寫掉特質中已經實作的方法或者屬性 則必須加 override 修飾
  * @param myname
  */
class Human(val myname: String) extends Attribute with Motion {

  //必須實作抽象屬性,可以不用override關鍵字
  val subject = "人類"
  def move(): Unit = ???

  //覆寫已經實作的屬性或者方法 必須使用override關鍵字
  override val name = myname
  override def eat(s: String): Unit = {println(name+"吃了"+s)}

  //類中定義的方法,列印對象資訊
  def printAttribute(): Unit = {
    println(state + subject + name)
  }
}

           
/**
  * 調用
  */
object Client extends App {

  private val human = new Human("張三")

  human.printAttribute()
  human.eat("面包")
}
           
  • 執行結果
活着的人類張三
張三吃了面包

Process finished with exit code 0
           

3.對象中混入特質(with)

/**
  * 定義個類
  */
class Animal {}

object AnimalClient extends App {

  //對象混入特質
  private val dog = new Animal with Attribute with Motion {
    
    //必須實作抽象方法和屬性
    val subject = "動物"
    def move(): Unit = println(name + "跑了起來")
    
    //可以覆寫已經實作的方法和屬性
    override val name = "狗"
    override def eat(s: String): Unit = println(name + "吃" + s)

  }

  println(dog.subject)
  println(dog.name)
  dog.eat("骨頭")
  dog.move()
  
}
           

執行結果

動物
狗
狗吃骨頭
狗跑了起來

Process finished with exit code 0
           

4.特質中調用super

/**
  * 特質中的super 調用的是下一層級中的方法 他仍然是一個抽象的
  * 必須添加 abstract override
  */
trait Botany extends Motion {
  abstract override def move(): Unit = super.move()
}