1.19
特质
概述
Scala 中的特质要用关键字 trait 修饰。
特点:
特质可以提高代码的复用性。
特质可以提高代码的扩展性和可维护性。
类与特质是继承关系,类与类只支持单继承,类与特质之间可以单继承也可以多继承。
Scala 的特质中可以有普通字段、抽象字段、普通方法、抽象方法。
如果特质只有抽象内容也叫瘦接口,如果既有抽象内容又有具体内容叫做富接口。
语法:
定义特质
trait 特质名称{
}
继承特质
class 类名 extends 特质1 with 特质2{
}
示例:类继承单个特质
object ClassDemo {
trait Logger{
def log(msg:String)
}
class ConsoleLogger extends Logger{
override def log(msg: String): Unit = println(msg)
}
def main(args: Array[String]): Unit = {
val logger = new ConsoleLogger
logger.log("hello scala")
}
}
示例:类继承多个特质
object ClassDemo {
trait MsgSender{
def send(msg:String)
}
trait MsgReceiver{
def receive()
}
class MsgWorker extends MsgSender with MsgReceiver{
override def send(msg: String): Unit = println(s"发送消息:$msg")
override def receive(): Unit = println("接收消息")
}
def main(args: Array[String]): Unit = {
val worker = new MsgWorker
worker.send("hello")
worker.receive()
}
}
示例:object 继承 trait
object ClassDemo {
trait MsgSender{
def send(msg:String)
}
trait MsgReceiver{
def receive()
}
object MsgWorker extends MsgSender with MsgReceiver{
override def send(msg: String): Unit = println(s"发送消息:$msg")
override def receive(): Unit = println("接收消息")
}
def main(args: Array[String]): Unit = {
MsgWorker.send("hello scala")
MsgWorker.receive()
}
}
示例:trait 中的成员
object ClassDemo {
trait Hero{
val name = ""
val arms = ""
def attack(): Unit = println("发起进攻")
def skill()
}
class Killer extends Hero{
override val name = "sjh"
override val arms = "gun"
override def skill(): Unit = println("kill")
}
def main(args: Array[String]): Unit = {
val killer = new Killer
killer.attack()
killer.skill()
}
}
对象混入 trait
在 Scala 中,类和特质之间无任何继承关系,但通过特定关键字让该类对象具有指定特质中的成员。
语法:
val/var 对象名 = new 类 with 特质
示例:
object ClassDemo {
trait Logger{
def log(): Unit = println("log..")
}
class User{
}
def main(args: Array[String]): Unit = {
val user = new User with Logger
user.log()//log..
}
}
使用 trait 实现适配器模式
当某个特质中有多个抽象方法,而我们只需要用到某个或某几个方法时不得不将该特质所有抽象方法重写。针对这种情况可以定义一个抽象类继承该特质,重写特质的所有方法,方法体为空。需要使用哪个方法只需要定义类继承抽象类,重写指定方法即可。
object ClassDemo {
trait Play{
def mid()
def top()
def adc()
def jungle()
def support()
}
abstract class Player extends Play{
override def mid(): Unit = {}
override def top(): Unit = {}
override def adc(): Unit = {}
override def jungle(): Unit = {}
override def support(): Unit = {}
}
//新手类
class GreenHand extends Player {
override def support(): Unit = println("我是辅助")
}
def main(args: Array[String]): Unit = {
val player = new GreenHand
player.support()
}
}
使用 trait 实现模板方法模式
在 Scala 中我们可以先定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该结构的情况下重定义该算法的某些特定步骤,这就是模板方法设计模式。
优点:扩展性强、符号开闭原则。
缺点:类的个数增加会导致系统庞大,设计更抽象、增加代码阅读难度。
object ClassDemo {
//模板类,计算某个方法的执行时间
abstract class Template{
def code()
def getRuntime: Long = {
val startTime = System.currentTimeMillis()
code()
val endTime = System.currentTimeMillis()
endTime - startTime
}
}
class Concrete extends Template{
override def code(): Unit = for(_ <- 1 to 10000) println("scala")
}
def main(args: Array[String]): Unit = {
println(s"耗时:${new Concrete().getRuntime} ms")
}
}
使用 trait 实现责任链模式
多个 trait 中出现了同一方法,且该方法最后都调用了 super.该方法名(),当类继承了这多个 trait 后就可以依次调用多个 trait 中的此同一个方法了,这就形成了一个调用链。
执行顺序:从右至左、先子类后父类。
示例:
object ClassDemo {
trait Handler{
def handle(data:String): Unit = {
println("具体的处理数据...4")
println(data)
}
}
trait DataValid extends Handler{
override def handle(data: String): Unit = {
println("验证数据 3")
super.handle(data)
}
}
trait SignValid extends Handler{
override def handle(data: String): Unit = {
println("验证签名 2")
super.handle(data)
}
}
class Payment extends DataValid with SignValid{
def pay(data:String): Unit = {
println("用户发起支付请求 1")
super.handle(data)
}
}
def main(args: Array[String]): Unit = {
val payment = new Payment
payment.pay("发起转账..5")
}
}

浙公网安备 33010602011771号