zoukankan      html  css  js  c++  java
  • scala trait 构建类对象 构建匿名子类

    在scala中 trait 可以认为是 Java中interface 跟abstract class 集中的混合体,JVM 8 中 特质可以包含具体方法跟抽象方法,自己理解下 如果一个特质中既有抽象方法又有具体方法时,别的类继承该特质时的背后流程。scala 中 可以允许特质的动态混入,

       构建对象的同时如果混入多个特质,称之为叠加特质

    object aiguigu {
      def main(args: Array[String]): Unit = {
        val t  = new T with T3
        t.myprint
        println("="*15)
        val t2 = new T with T4
        t2 myprint
      }
    }
    
    trait T1{
      println("T1 is created")
      def myprint = println("T1 is my print")
    }
    trait T2{
      println("T2 is created")
      def myprint = println("T2 is my print")
    }
    
    trait T3 extends T1 with T2 {
      println("T3 is created")
    
      override def myprint: Unit = super.myprint
    }
    
    trait T4 extends T2 with T1 {
      println("T3 is created")
    
      override def myprint: Unit = super.myprint
    }
    
    class T {}
    

     结果如下:

    T1 is created
    T2 is created
    T3 is created
    T2 is my print
    ===============
    T2 is created
    T1 is created
    T3 is created
    T1 is my print
    object aiguigu {
      def main(args: Array[String]): Unit = {
        val mysql = new MySQL4 with DB4 with File4
        mysql.insert(100)
      }
    }
    
    trait Operate4 {
      println("Operate4")
      def insert(id: Int)
    }
    
    trait Data4 extends Operate4 {
      println("Data4")
      def insert(id: Int): Unit = {
        println("插入数据 = " + id)
      }
    }
    
    trait DB4 extends Data4 {
      println("DB4")
      override def insert(id: Int): Unit = {
        println("向数据库")
        super.insert(id)
      }
    }
    
    trait File4 extends Data4 {
      println("File4")
      override def insert(id: Int): Unit = {
        println("向文件")
        super.insert(id)
        // super[Data4].insert(id)
      }
    }
    
    class MySQL4{}

    结果如下: 

    Operate4
    Data4
    DB4
    File4
    向文件
    向数据库
    插入数据 = 100

    结果:

    1. trait 特质实例化的执行顺序是:从左到右   
    2. trait 调用多个同名方法时执行顺序是:从右到左 , 如果特质中调用了super,并不是表示调用父特质的方法,而是向前(向左) 继续查找特质,如果找不到才会去父特质查找。
    3. 如果想要调用具体特质的方法 可以指定super[特质].xxx(...) 其中的泛型必须是该特质的直接超类类型。 比如 super[Data4].insert(id) 执行顺序如下
      Operate4
      Data4
      DB4
      File4
      向文件
      插入数据 = 100
    
    object tiger {
      def main(args: Array[String]): Unit = {
        /*
        构建类对象, 在混入特质时,该对象还没有创建
        调用当前类的超类构造器
        第一个特质的父特质构造器
        第一个特质构造器
        第二个特质构造器的父特质构造器, 如果已经执行过, 就不再执行
        第二个特质构造器
        .......重复 4,5 的步骤(如果有第 3 个,第 4 个特质) 当前类构造器 [案例演示]
        */
        //1. E...
        //2. A...
        //3. B....
        //4. C....
        //5. D....
        //6. F....
        val ff1 = new FF()
        println(ff1)
    
        /*
        构造匿名子类,可以理解成在混入特质时,对象已经创建了
        先创建 new KK 对象,然后再混入其它特质
        调用当前类的超类构造器
        当前类构造器
        第一个特质构造器的父特质构造器
        第一个特质构造器.
        第二个特质构造器的父特质构造器, 如果已经执行过,就不再执行 第二个特质构造器
        .......重复 5,6 的步骤(如果有第 3 个,第 4 个特质)
        当前类构造器 [案例演示]
        */
        //1. E...
        //2. K....
        //3. A...
        //4. B
        //5. C
        //6. D
        println("=======================")
        val ff2 = new KK with CC with DD
        println(ff2)
      }
    }
    
    trait AA { println("A...")}
    trait BB extends AA { println("B....")}
    trait CC extends BB { println("C....")}
    trait DD extends BB { println("D....")}
    class EE {  println("E...")}
    class FF extends EE with CC with DD { //先继承了 EE 类,然后再继承 CC 和 DD
      println("F....")
    }
    class KK extends EE { // KK 直接继承了普通类 EE   构造匿名子类,可以理解成在混入特质时,对象已经创建了
      println("K....")
    }

     分析两种方式对构造顺序的影响
    第 1 种方式实际是构建类对象, 在混入特质时,该对象还没有创建。
    第 2 种方式实际是构造匿名子类,可以理解成在混入特质时,对象已经创建了然后添加特质属性。

    关注公众号 海量干货等你
  • 相关阅读:
    CodeForces 408E Curious Array(组合数学+差分)
    CodeForces 519E A and B and Lecture Rooms(倍增)
    洛谷 4051 [JSOI2007]字符加密(后缀数组)
    哇,两门学考都是A(〃'▽'〃)
    BZOJ 1977 严格次小生成树
    XJOI 3606 最大子矩形面积/LightOJ 1083 Histogram(单调栈/笛卡尔树)
    XJOI 3629 非严格次小生成树(pqq的礼物)
    XJOI 3363 树4/ Codeforces 739B Alyona and a tree(树上差分+路径倍增)
    [转载]别让用户发呆—设计中的防呆策略
    Linux下的链接文件
  • 原文地址:https://www.cnblogs.com/sowhat1412/p/12734171.html
Copyright © 2011-2022 走看看