Trait的定義及使用
Trait的設計及功能
- Trait的設計類似于Java中Interface的設計,可以當做Java中的Interface來使用,但是比接口的功能更加強大
- 當Trait當做Interface來使用時,基本與Interface沒有差別
Trait的定義文法
- 關鍵字:trait
- 定義
trait HelloTrait { //抽象方法 def sayHello } trait ByeTrait { def sayBye }
Trait的使用
- 關鍵字:extends
- Scala中類的繼承和Trait的實作都使用extends來表示
- 實作多個關鍵字:with
class Person06 extends HelloTrait with ByeTrait with Serializable { //實作接口中的抽象方法 override def sayHello: Unit = println("Hello ~ Person") override def sayBye: Unit = println("Bye ~ Person") } object Person06{ def main(args: Array[String]): Unit = { val p1 = new Person06 p1.sayHello p1.sayBye } }
Trait實作工具類的封裝
Trait中的方法定義
- 抽象方法:隻定義方法名,沒有方法體,沒有實作邏輯
- 具體方法:定義了方法名和方法體,包含了實作邏輯
- Trait中既可以定義抽象方法,也可以定義具體方法
Trait實作封裝工具類
- 在Trait中定義具體的方法,所有繼承了該Trait的類都具有了該方法
- 建構一個工具類的父類:包含通用的工具方法
- TimeUtils:時間字元串的剪切和拼接
- URLUtils:剪切和拼接url
- 需求:建構一個Trait,實作切分字元串和拼接字元串
- 測試
trait StringUtilsTrait { //可以定義抽象方法和屬性,當做接口來實作 //可以定義具體的方法和屬性 def subStr(str:String,start:Int,len:Int):String = { str.substring(start,start+len) } def concatStr(sep:String,str:String *):String = { str.mkString(sep) } } object TimeUtils extends StringUtilsTrait {} object URLUtils extends StringUtilsTrait{} object TestTrait{ def main(args: Array[String]): Unit = { val str1 = "I" val str2 = "like" val str3 = "learning" println(TimeUtils.subStr(str3,0,5)) println(TimeUtils.concatStr("-",str1,str2,str3)) } }
執行個體混入Trait
執行個體混入Trait的介紹
- 執行個體混入Trait指的是為了解決相同類的不同執行個體繼承不同Trait的問題
- 在建構同一個類的執行個體時,可以指定目前執行個體化的對象繼承哪些Trait
執行個體混入Trait的文法
val 對象名稱 = new 類 with Trait1 with Trait2 ……
執行個體混入Trait的實作
- 執行個體混入Trait指的是為了解決相同類的不同執行個體繼承不同Trait的問題
- 在建構同一個類的執行個體時,可以指定目前執行個體化的對象繼承哪些Trait
- 正常的trait的繼承:定義類的實作繼承
class Person extends Trait class Person01 extends HelloTrait { override def sayHello: Unit = println("Hello Person") } object TestPerson01{ def main(args: Array[String]): Unit = { val p1 = new Person01 p1.sayHello val p2 = new Person01 p2.sayHello } }
- 執行個體混入trait:指的是可以在建構對象的時候來實作繼承Trait
執行個體混入Trait的文法
val 對象名稱 = new 類 with Trait1 with Trait2 ……
執行個體混入Trait的實作
- 需求1:對象1能sayHello,對象2不能
}
object TestPerson01{
def main(args: Array[String]): Unit = {
val p1 = new Person01 with HelloTrait {
override def sayHello: Unit = println("Hello")
}
p1.sayHello
val p2 = new Person01
p2.sayHello //報錯
}
}
```
- 需求2:對象1能sayHello,對象2能sayBye
class Person01 { } object TestPerson01{ def main(args: Array[String]): Unit = { val p1 = new Person01 with HelloTrait { override def sayHello: Unit = println("Hello") } p1.sayHello val p2 = new Person01 with ByeTrait { override def sayBye: Unit = println("Bye") } p2.sayBye } }
- 需求3:對象1能sayHello,對象1和對象2都能sayBye,對象2能拼接字元串
class Person01 { } object TestPerson01{ def main(args: Array[String]): Unit = { val p1 = new Person01 with HelloTrait with ByeTrait { override def sayHello: Unit = println("Hello") override def sayBye: Unit = println("Bye") } p1.sayHello p1.sayBye val p2 = new Person01 with ByeTrait with StringUtilsTrait { override def sayBye: Unit = println("Bye") } p2.sayBye p2.concatStr("-","I","like") } } class Person01 extends ByeTrait { override def sayBye: Unit = println("Bye") } object TestPerson01{ def main(args: Array[String]): Unit = { val p1 = new Person01 with HelloTrait { override def sayHello: Unit = println("Hello") } p1.sayHello p1.sayBye val p2 = new Person01 with StringUtilsTrait p2.sayBye p2.concatStr("-","I","like") } }
Trait的構造機制及Trait繼承Class
- **Trait的構造器**
- Trait不支援構造參數,但是每個Trait都有一個無參構造器
- 類中:除了成員屬性和成員方法外,其他的所有代碼都屬于主構造器
class Person02(var name:String,var age:Int) { println("Start ……………………") //成員屬性 var country :String = "China" //成員方法 def sayHello = println("Hello") println("End ……………………") } object Person02{ def main(args: Array[String]): Unit = { val itcast = new Person02("itcast",18) itcast.sayHello } }
類的基本構造順序
- 從左到右依次執行繼承的父類或者Trait的構造,再執行自身的構造
- 繼承一個類
class Person02() { println("Start Person ……………………") println("End Person ……………………") } class Student02 extends Person02{ println("Start Student ……………………") println("End Student ……………………") } object Person02{ def main(args: Array[String]): Unit = { val student = new Student02 } }
- 繼承一個類和兩個Trait
class Person02() { println("Start Person ……………………") } trait HelloTrait1 { println("Start HelloTrait ……") } trait ByeTrait1 { println("Start ByeTrait ……") } class Student02 extends Person02 with HelloTrait1 with ByeTrait1 { println("Start Student ……………………") } object Person02{ def main(args: Array[String]): Unit = { val student = new Student02 } }
複雜繼承的構造順序
- 如果一個類繼承多個Trait,而Trait又繼承父Trait,先構造父Trait,再構造子Trait
- 如果多個子Trait的父Trait相同,則父Trait隻構造一次
- 繼承關系
```scala
class Student extends Person with MyLogger with TimeLogger
Trait MyLogger extends Logger
Trait TimeLogger extends Logger
```
- 構造順序
class Person02() { println("Start Person ……………………") } trait Logger{ println("Strat Logger ……") } trait MyLogger extends Logger { println("Start MyLogger ……") } trait TimeLogger extends Logger { println("Start TimeLogger ……") } class Student02 extends Person02 with MyLogger with TimeLogger { println("Start Student ……………………") } object Person02{ def main(args: Array[String]): Unit = { val student = new Student02 } }
Trait繼承Class的實作
- class extends Trait:類繼承Trait
- trait extends Class:Trait繼承類
class Person03 { def sayWhat = println("I like leanring") } trait PersonTrait extends Person03{ def sayBye } class Student extends PersonTrait{ override def sayBye: Unit = println("bye") } object Stduent{ def main(args: Array[String]): Unit = { val student = new Student student.sayBye student.sayWhat } }
- 如果一個類的執行個體調用了一個方法
- 這個方法不在這個類中,也不在實作的接口中,可能在接口的父類中
點個贊嘛!