38_面向对象_Trait

特征(Trait)
* 说明
* 1. scala中的Trait,相当于java中的接口+抽象类,可以实现多继承
* 2. trait中可以有抽象属性和抽象方法 也可以有非抽象属性和方法
* 3. 一个类可以继承多个trait / 一个类可以混入(mixin)多个特质
* 语法
* 声明
* trait 名称 { 成员 }
* 继承
* 没有父类 class 类名 extends 特征1 with 特征2 ...
* 有父类 class 类名 extends 父类 with 特征1 with 特征2 ...
* 说明
* 1. 当一个继承trait时,第一个trait用extends,第二个用with
* 2. 同时继承trait和父类时,父类写在extends后面,trait写在with后面
*
动态混入
* 创建对象时mixin 特质,无需在类定义时mixin
* 示例
* var obj = new 对象名称 with 特质1 { 实现 }
*
* 混入多个特质,且多个特质具有相同属性/方法
* 示例
* with Atrait with Btrait
* 情况1
* Atrait、Btrait无关
* 1. 当属性或方法相同时,必须在实现类中重写相同的方法或属性
* 2. 当非抽象属性相同时,他们必须为val变量
* 情况2(特质叠加)
* Atrait、Btrait有关有共同的父类 Ctrait (钻石问题)
* 示例
* class ThreeClass extends Atrait with Btrait
* 说明
* 1. 当属性或方法相同时,优先按继承顺序,使用靠后的特质
* ThreeClass -> Btrait -> Atrait -> Ctrait
* ThreeClass.super = Btrait
* Btrait.super = Atrait
* Atrait.super = Ctrait
* 2. 在实现类中可以使用 super[特质名称].成员 来限制继承顺序
*
特质自身类型
* 说明
* 自身类型可以实现依赖注入功能
* 语法
* _: traitName =>
* 等价于 混入traitName
*
* */
复制代码
package com.dawang.scala.面向对象

/**
  * @author gaocun
  * @create 2021-10-25 6:41 PM */
class Trait_12 {
  /*
  * 特征(Trait)
  *    说明
  *       1. scala中的Trait,相当于java中的接口+抽象类,可以实现多继承
  *       2. trait中可以有抽象属性和抽象方法 也可以有非抽象属性和方法
  *       3. 一个类可以继承多个trait / 一个类可以混入(mixin)多个特质
  *    语法
  *       声明
  *          trait 名称 { 成员 }
  *       继承
  *           没有父类 class 类名 extends 特征1 with 特征2 ...
  *           有父类   class 类名 extends 父类 with 特征1 with 特征2 ...
  *       说明
  *           1. 当一个继承trait时,第一个trait用extends,第二个用with
  *           2. 同时继承trait和父类时,父类写在extends后面,trait写在with后面
  *
  *    动态混入
  *       创建对象时mixin 特质,无需在类定义时mixin
  *       示例
  *          var obj = new 对象名称 with 特质1 { 实现 }
  *
  *    混入多个特质,且多个特质具有相同属性/方法
  *        示例
  *             with Atrait with Btrait
  *        情况1
  *             Atrait、Btrait无关
  *             1. 当属性或方法相同时,必须在实现类中重写相同的方法或属性
  *             2. 当非抽象属性相同时,他们必须为val变量
  *        情况2(特质叠加)
  *             Atrait、Btrait有关有共同的父类 Ctrait (钻石问题)
  *             示例
  *                 class ThreeClass extends Atrait with Btrait
  *             说明
  *                 1. 当属性或方法相同时,优先按继承顺序,使用靠后的特质
  *                     ThreeClass -> Btrait -> Atrait -> Ctrait
  *                     ThreeClass.super = Btrait
  *                     Btrait.super = Atrait
  *                     Atrait.super = Ctrait
  *                 2. 在实现类中可以使用 super[特质名称].成员 来限制继承顺序
  *
  *     特质自身类型
  *       说明
  *           自身类型可以实现依赖注入功能
  *       语法
  *           _: traitName =>
  *           等价于 混入traitName
  *
  * */
}

package Outer12 {

  // 声明 trait
  trait OneTrait {
    // 抽象属性 + 非抽象属性
    var id: Int
    var name: String = "大王"

    // 抽象方法 + 非抽象方法
    def abs_show

    def show = println("OneTrait - 非抽象方法")

    println("OneTrait - 主构造器")
  }

  class OneClass {}

  trait Atrait {
    val id: Int = 1
    val name = "Atrait"

    def show = println("Atrait - show")
  }

  trait Btrait {
    val id: Int = 2
    val name = "Btrait"

    def show = println("Btrait - show")
  }

  // 声明类 混入多个特质(A B且A、B无关)
  class TwoClass extends Atrait with Btrait {
    override def show: Unit = println("TwoClass - 重新show方法")

    override val id: Int = 88
    override val name = "OneClass"

  }

  trait Ctrait {
    val id = 1
    val name = "Ctrait"

    def show = {
      println("Ctrait - show执行了")
      "Ctrait"
    }
  }

  trait Dtrait extends Ctrait {
    override val id = 2
    override val name = "Dtrait"

    override def show = {
      println("Dtrait - show执行了")
      super.show + "-" + "Dtrait"
    }
  }

  trait Etrait extends Ctrait {
    override val id = 3
    override val name = "Etrait"

    override def show = {
      println("Etrait - show执行了")
      super.show + "-" + "Dtrait"
    }
  }

  class ThreeClass extends Etrait with Dtrait with Ctrait {
    // 使用super[]来指定混入的trait
    override def show: String = super[Ctrait].show
  }


  // 测试
  object test12 {
    def main(args: Array[String]): Unit = {
      // 动态混入
      var obj = new OneClass with OneTrait {
        override var id: Int = 99

        override def abs_show: Unit = "OneTrait - 动态混入"
      }
      println(obj.id)
      println(obj.name)
      obj.show
      obj.abs_show
      println("===========================")
      var obj1 = new TwoClass()
      obj1.show
      println(obj1.id)
      println(obj1.name)
      println("===========================")
      var obj2 = new ThreeClass()
      println(obj2.id)
      println(obj2.name)
      println(obj2.show)
      println("===========================")


    }
  }

}


package Outer12_1 {

  // 定义类
  class User(val id: Int, val name: String)

  // 定义Dao特质
  trait Dao {
    // 非抽象方法
    def insert(user: User) = {
      println("insert into database" + user.name)
    }
    println("Dao - 主构造器")
  }

  // 定义APP特质
  trait App  {
    // 依赖注入
    _: Dao =>

    // 非抽象方法
    def login(user: User) = {
      println("login :" + user.name)
      insert(user)
    }
  }

  // 实现类
  object MyApp extends App with Dao {
    def main(args: Array[String]): Unit = {
      login(new User(10,"大王"))
    }
  }

}
复制代码

 

posted @   学而不思则罔!  阅读(65)  评论(0编辑  收藏  举报
编辑推荐:
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· 字符编码:从基础到乱码解决
· SpringCloud带你走进微服务的世界
点击右上角即可分享
微信分享提示