特質
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()
}