特质 #

一、特质基础 #

1.1 什么是特质 #

特质(Trait)是 Scala 中代码复用的基本单元,类似于 Java 的接口,但更强大:

  • 可以包含抽象方法
  • 可以包含具体方法
  • 可以包含字段
  • 可以多继承

1.2 定义特质 #

scala
trait Greeting:
  def greet(name: String): String = s"Hello, $name!"

class Person extends Greeting:
  def welcome(): String = greet("World")

val person = Person()
println(person.welcome())

1.3 抽象方法 #

scala
trait Animal:
  def name: String
  def speak(): String

class Dog(val name: String) extends Animal:
  override def speak(): String = "Woof!"

val dog = Dog("Rex")
println(dog.speak())

二、混入特质 #

2.1 单个特质 #

scala
trait Logging:
  def log(message: String): Unit = println(s"[LOG] $message")

class Service extends Logging:
  def process(): Unit =
    log("Processing...")

val service = Service()
service.process()

2.2 多个特质 #

使用 with 关键字:

scala
trait Logging:
  def log(msg: String): Unit = println(s"[LOG] $msg")

trait Timing:
  def time[T](block: => T): T =
    val start = System.nanoTime()
    val result = block
    val end = System.nanoTime()
    println(s"Time: ${(end - start) / 1e6} ms")
    result

class Service extends Logging with Timing:
  def process(): Unit =
    time {
      log("Processing...")
      Thread.sleep(100)
    }

2.3 动态混入 #

scala
trait Logging:
  def log(msg: String): Unit = println(s"[LOG] $msg")

class Service:
  def process(): Unit = println("Processing...")

val serviceWithLogging = new Service with Logging:
  override def process(): Unit =
    log("Starting process")
    super.process()
    log("Process completed")

serviceWithLogging.process()

三、特质字段 #

3.1 具体字段 #

scala
trait Counter:
  var count = 0
  def increment(): Int =
    count += 1
    count

class MyCounter extends Counter

val counter = MyCounter()
println(counter.increment())
println(counter.increment())

3.2 抽象字段 #

scala
trait Config:
  val host: String
  val port: Int
  def url: String = s"http://$host:$port"

class DevConfig extends Config:
  override val host: String = "localhost"
  override val port: Int = 8080

val config = DevConfig()
println(config.url)

3.3 lazy 字段 #

scala
trait HeavyResource:
  lazy val data: String =
    println("Loading data...")
    "Heavy data loaded"

class MyResource extends HeavyResource:
  def use(): String = data

val resource = MyResource()
println("Created")
println(resource.use())

四、特质叠加 #

4.1 方法叠加顺序 #

从右到左执行:

scala
trait A:
  def greet(): String = "A"

trait B extends A:
  override def greet(): String = s"B -> ${super.greet()}"

trait C extends A:
  override def greet(): String = s"C -> ${super.greet()}"

class D extends B with C:
  override def greet(): String = s"D -> ${super.greet()}"

val d = D()
println(d.greet())

4.2 线性化 #

scala
trait Base:
  def method(): String = "Base"

trait A extends Base:
  override def method(): String = s"A -> ${super.method()}"

trait B extends Base:
  override def method(): String = s"B -> ${super.method()}"

class C extends A with B:
  override def method(): String = s"C -> ${super.method()}"

val c = C()
println(c.method())
println(c.method())

4.3 super 调用 #

scala
trait Logging:
  def log(msg: String): Unit = println(s"[LOG] $msg")

trait DebugLogging extends Logging:
  override def log(msg: String): Unit =
    super.log(s"[DEBUG] $msg")

trait ErrorLogging extends Logging:
  override def log(msg: String): Unit =
    super.log(s"[ERROR] $msg")

class MyService extends DebugLogging with ErrorLogging:
  def process(): Unit = log("Processing...")

val service = MyService()
service.process()

五、特质与抽象类 #

5.1 特质的优势 #

  • 可以多继承
  • 可以动态混入
  • 适合作为小型功能模块

5.2 抽象类的优势 #

  • 可以有构造函数参数
  • 更好的 Java 互操作性
  • 更清晰的继承关系

5.3 选择建议 #

场景 推荐
定义行为接口 Trait
代码复用 Trait
有构造参数 Abstract Class
需要Java调用 Abstract Class
不确定 Trait

六、特质实战 #

6.1 日志系统 #

scala
trait Logger:
  def log(level: String, message: String): Unit

trait ConsoleLogger extends Logger:
  override def log(level: String, message: String): Unit =
    println(s"[$level] $message")

trait FileLogger extends Logger:
  override def log(level: String, message: String): Unit =
    val writer = java.io.FileWriter("app.log", true)
    writer.write(s"[$level] $message\n")
    writer.close()

class Application extends ConsoleLogger:
  def run(): Unit =
    log("INFO", "Application started")
    log("DEBUG", "Processing data")
    log("INFO", "Application finished")

val app = Application()
app.run()

6.2 缓存系统 #

scala
trait Cache[K, V]:
  def get(key: K): Option[V]
  def put(key: K, value: V): Unit
  def remove(key: K): Unit
  def clear(): Unit

trait MemoryCache[K, V] extends Cache[K, V]:
  private val store = scala.collection.mutable.Map.empty[K, V]
  
  override def get(key: K): Option[V] = store.get(key)
  override def put(key: K, value: V): Unit = store.put(key, value)
  override def remove(key: K): Unit = store.remove(key)
  override def clear(): Unit = store.clear()

trait ExpiringCache[K, V] extends Cache[K, V]:
  private val timestamps = scala.collection.mutable.Map.empty[K, Long]
  val ttl: Long = 60000
  
  abstract override def get(key: K): Option[V] =
    timestamps.get(key) match
      case Some(ts) if System.currentTimeMillis() - ts > ttl =>
        remove(key)
        None
      case _ => super.get(key)
  
  abstract override def put(key: K, value: V): Unit =
    timestamps.put(key, System.currentTimeMillis())
    super.put(key, value)
  
  abstract override def remove(key: K): Unit =
    timestamps.remove(key)
    super.remove(key)
  
  abstract override def clear(): Unit =
    timestamps.clear()
    super.clear()

class MyCache extends MemoryCache[String, String] with ExpiringCache[String, String]

6.3 观察者模式 #

scala
trait Observer[A]:
  def update(value: A): Unit

trait Observable[A]:
  private var observers = List.empty[Observer[A]]
  
  def addObserver(observer: Observer[A]): Unit =
    observers = observer :: observers
  
  def notifyObservers(value: A): Unit =
    observers.foreach(_.update(value))

class Sensor extends Observable[Double]:
  def setValue(value: Double): Unit =
    notifyObservers(value)

class Display extends Observer[Double]:
  override def update(value: Double): Unit =
    println(f"Display: $value%.2f")

val sensor = Sensor()
sensor.addObserver(Display())
sensor.setValue(25.5)

七、特质最佳实践 #

7.1 小而专注 #

scala
trait Logging:
  def log(msg: String): Unit

trait Timing:
  def time[T](block: => T): T

trait Validation:
  def validate[T](value: T)(rules: T => Boolean*): Boolean

7.2 使用抽象成员 #

scala
trait Repository[K, V]:
  def findById(id: K): Option[V]
  def save(entity: V): Unit
  def delete(id: K): Unit

7.3 组合优于继承 #

scala
class Service extends Logging with Timing with Validation:
  def process(): Unit =
    time {
      log("Processing...")
    }

八、总结 #

特质特性 #

特性 说明
抽象方法 必须由子类实现
具体方法 可直接使用
字段 支持抽象和具体字段
多继承 使用 with 组合
动态混入 运行时添加功能

混入顺序 #

text
class C extends A with B with C

执行顺序:C -> B -> A

下一步,让我们学习 样例类

最后更新:2026-03-27