天天看點

【Scala快速入門】--TraitTrait的定義及使用Trait實作工具類的封裝Trait的構造機制及Trait繼承Class

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快速入門】--TraitTrait的定義及使用Trait實作工具類的封裝Trait的構造機制及Trait繼承Class
```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
      }
    }
               
    • 如果一個類的執行個體調用了一個方法
    • 這個方法不在這個類中,也不在實作的接口中,可能在接口的父類中

點個贊嘛!

【Scala快速入門】--TraitTrait的定義及使用Trait實作工具類的封裝Trait的構造機制及Trait繼承Class

繼續閱讀