scala接口trait

Scala 接口的介绍

Scala 语言中,采用特质trait(特征)来代替接口的概念,也就是说,多个类具有相同的特征时,就可以将这个特质(特征)独立出来,采用关键字 trait 声明。理解 trait 就等价与(interface+abstract class)

  • trait 的声明

    trait 特质名{
        trait}
    

    trait 命名 一般字母大写。

    Cloneable,Serializable

    object T1 extends Serializable{
        
    }
    

    Serializable:就是 scala 的一个特质。

    在 scala 中,java 中的接口可以当做特质使用

  • Scala 中 trait 的使用

    一个类具有某种特质(特征),就意味着这个类满足了这个特质(特征)的所有要素,所以在使用时,也采用了 extends 关键字,如果由多个特质或存在父类,那么需要采用 with 关键字链接

    • 没有父类

      class 类名 extends 特质1 with 特质2 with 特质3..
      
    • 有父类

      class 类名 extends 父类 with 特质1 with 特质2 with 特质3
      
  • 带有具体实现的特质

    说明:和 Java 中的接口不太一样的时特质中的方法并不一定时抽象的,也可以有非抽象方法(即:实现了的方法)。

    trait Operate{
        def insert(id:Int):Unit={
            println("保存数据="+id)
        }
    }
    
    trait DB extends Operate{
        override def insert(id:Int):Unit={
            print("向数据库中")
            super.insert(id)
        }
        
    }
    class MySQL extends DB{
        
    }
    
  • 带有特质的对象,动态混入

    1. 出了可以在类声明时继承特质外,还可以在构建对象时混入特质,扩展目标类的功能【反编译看动态混入本质】
    2. 此种方式也可以应用于对抽象类功能进行扩展
    3. 动态混入是Scala特有的方式(java没有动态混入),可在不修改类申明/定义的情况下,扩展类的功能,非常灵活,耦合性低。
    4. 动态混入可以在不影响原有的继承关系的基础上,给指定的类扩展功能。
    trait Operate3 {
    	def insert(id:Int): Unit = {
    		println("插入数据 = " + id)
    	}
    }
    
    class OracleDB {	
    }
    abstract class MySQL3 {
    }
    
    var oracle = new OracleDB with Operate3
    oracle.insert(999)
    val mysql = net MySQL3 with Operate3
    mysql.insert(4)
    
  • 叠加特质

object LearningTrait {

  trait Logged {  //最上层级的特质
    def log(msg: String) {
      //什么都不做
    }
  }

  trait ConsoleLogger extends Logged {  //重写了Logged特质的log方法,输出消息
    //用extends,而不是implements
    override def log(msg: String) {
      println(msg) //不需要写override
    }
  }

  trait TimestampLogger extends Logged {  //重写了Logged特质的log方法,并在log方法中调用下一层特质的log方法
    override def log(msg: String) {
      super.log(new java.util.Date() + " " + msg) //将当前时间与消息拼接,并传递给下一层特质的log方法
    }
  }

  trait ShortLogger extends Logged {  //重写了Logged特质的log方法,并在log方法中调用下一层特质的log方法
    val maxLength = 15
    //关于特质中的字段,后续内容将会详细讲解
    override def log(msg: String) {
      super.log(if (msg.length <= maxLength) msg else msg.substring(0, maxLength - 3) + "...") //判断msg变量的长度是否超过了maxLength,如果超过,删除最后三个字符,并将其传递给下一层特质的log方法
    }
  }

 
 class Account{  //一个基类,有一个成员字段balance,表示余额
    var balance = 1.2
  }

  class SavingsAccount extends  Account with Logged{
    def withdraw(amount: Double){
      if(amount > balance) log("Insufficient funds")   //使用if语句进行判断,如果if中的条件,则调用特质中的log方法
      else balance -= amount
    }
  }

  def main(args: Array[String]) {

    //声明两个对象,并添加多个特质,其中顺序有稍许差别,acct1添加的顺序为ConsoleLogger、TimestampLogger、ShortLogger,acct2的顺序为ConsoleLogger、Timestamp、ShortLogger
    val acct1 = new SavingsAccount with ConsoleLogger with TimestampLogger with ShortLogger
    val acct2 = new SavingsAccount with ConsoleLogger with ShortLogger with TimestampLogger

    //两个对象均调用withdraw方法
    acct1.withdraw(2.5)
    acct2.withdraw(2.5)
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码上行舟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值