Scala快速入门--Trait

Posted 一只楠喃

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Scala快速入门--Trait相关的知识,希望对你有一定的参考价值。

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 对象名称 = newwith 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 对象名称 = newwith Trait1 with Trait2 ……

实例混入Trait的实现

  • 需求1:对象1能sayHello,对象2不能

    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
    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
      }
    }
    
    • 如果一个类的实例调用了一个方法
    • 这个方法不在这个类中,也不在实现的接口中,可能在接口的父类中

点个赞嘛!在这里插入图片描述

以上是关于Scala快速入门--Trait的主要内容,如果未能解决你的问题,请参考以下文章

初学scala4——trait混入

Scala入门系列:面向对象之trait

Scala编程入门---面向对象编程之Trait高级知识

快学Scala 第十七课 (trait 入门)

Scala入门:面向对象编程之Trait 详解

Scala编程入门---面向对象编程之Trait