Scala 特质(trait)案例解析:多继承、属性与方法的灵活运用

48 阅读3分钟

一、结构解释

代码包含 3 个核心组件 + 1 个测试入口:

  1. 特质 BeautifulEye:仅包含具体属性
  2. 特质 Tall:包含具体属性具体方法抽象方法
  3. 类 Child:通过 extends + with 实现多特质继承,并重写抽象方法
  4. main 方法:程序入口,创建 Child 实例并测试所有功能

二、代码解释

特质 仅包含具体属性

trait BeautifulEye {
  val eye: String = "眼睛漂亮"
}
  • trait 是 Scala 中 “特质” 的关键字,特质类似 Java 的接口,但功能更强(可包含具体实现)

  • val eye: String = "眼睛漂亮":这是 具体属性(有明确初始值)

    • val 表示不可变属性(值一旦赋值不能修改)
    • 类型声明为 String,初始值是 "眼睛漂亮"
    • 特质中的属性默认是 public,实现类可直接继承使用

特质:包含具体属性、具体方法、抽象方法

trait Tall {
  // 1. 具体属性(有初始值)
  val height: String = "大高个"

  // 2. 具体方法(有完整实现逻辑)
  def run(): Unit = {
    println("run...")
  }

  // 3. 抽象方法(仅声明方法签名,无实现)
  def jump(): Unit
}
  • 这是一个复合型特质,包含三种元素:
    1. 具体属性 height:不可变字符串,初始值 "大高个",继承后可直接使用

    2. 具体方法 run()

      • 用 def 定义,有完整的方法体(println("run...")
      • 实现类继承后无需重写,可直接调用
    3. 抽象方法 jump(): Unit

      • 仅声明方法名、参数列表(无参数)、返回值(Unit 表示无返回值)
      • 无方法体,实现类必须强制重写(否则编译报错)

类 :多特质继承与抽象方法重写

class Child extends BeautifulEye with Tall {
  // 自身属性(类自己定义的成员)
  val name: String = "小花"

  // 重写特质 Tall 中的抽象方法 jump()
  def jump(): Unit = {
    println(s"${name},jump....")
  }
}
  • 核心语法:extends + with 实现多特质继承
    • extends BeautifulEye:Scala 中类只能用 extends 继承一个 “主特质 / 类”,这里主特质是 BeautifulEye
    • with Tall:用 with 追加继承其他特质,支持无限多个
  • 类的成员说明:
    1. val name: String = "小花"Child 类自己定义的具体属性,与继承的特质无关
    2. 重写 jump() 方法:
      • 因为 Tall 特质中的 jump() 是抽象方法(无实现),所以 Child 必须重写
      • 重写时无需加 override 关键字(Scala 对抽象方法的重写默认允许省略,加了也不报错)
      • 方法体中用 s"${name},jump...." 是字符串插值语法,将 name 的值嵌入字符串

5. main 方法:测试逻辑与运行流程

def main(args: Array[String]): Unit = {
  // 1. 创建 Child 类的实例
  val child = new Child()

  // 2. 访问继承自 BeautifulEye 特质的具体属性 eye
  println(child.eye)

  // 3. 访问继承自 Tall 特质的具体属性 height
  println(child.height)

  // 4. 调用继承自 Tall 特质的具体方法 run()
  child.run()

  // 5. 调用重写后的 jump() 方法
  child.jump()
}
  • main 方法是程序的入口,参数 args: Array[String] 用于接收命令行参数
  • 运行步骤拆解:
    1. val child = new Child():创建 Child 实例,此时会自动继承 BeautifulEye 和 Tall 的所有非抽象成员
    2. child.eye:访问继承的具体属性,输出 "眼睛漂亮"
    3. child.height:访问继承的具体属性,输出 "大高个"
    4. child.run():调用继承的具体方法,执行 println("run...")
    5. child.jump():调用重写后的方法,执行 println("小花,jump....")

三、运行结果

眼睛漂亮
大高个
run...
小花,jump....
  • 输出顺序与 main 方法中调用顺序一致
  • 继承的属性 / 方法直接生效,重写的方法覆盖了特质中的抽象声明,符合 Scala 特质的继承规则
此次案例的完整代码
/*
 * 特质
 * trait: 实现多继承
 * 1.具体属性,抽象属性
 * 2.具体方法,抽象方法
 *
 * 具体属性和抽象属性,怎么区分
 * 有具体值的,是具体属性
 */

object day010 {
  trait BeautifulEye {
    val eye:String = "眼睛漂亮"
  }

  trait  Tall {
    val height:String = "大高个"
    def run():Unit ={
      println("run...")
    }
    def jump():Unit
  }

  // 继承 with
  class Child extends BeautifulEye with Tall{
    val name:String = "小花"
    def jump():Unit = {
      println(s"${name},jump....")
    }

  }

  def main(args: Array[String]): Unit = {
    val child = new Child()
    println(child.eye)
    println(child.height)
    child.run()
    child.jump()
  }

最终总结

核心知识点回顾

  1. 特质的多继承:用 extends + with 实现

  2. 具体属性 vs 抽象属性:

    • 具体属性:有初始值(如 eye: String = "眼睛漂亮"height: String = "大高个"
    • 抽象属性:仅声明类型,无初始值(如 val age: Int,代码中未添加,可自行添加)
  3. 具体方法 vs 抽象方法:

    • 具体方法:有方法体(如 run(): Unit = { println("run...") }
    • 抽象方法:无方法体(如 def jump(): Unit),实现类必须重写
  4. 特质的作用:代码复用(多个类可继承同一个特质)、实现多继承能力(一个类可继承多个特质)