Scala中的类的继承(二)

34 阅读3分钟

Scala 中的类的继承(二)

1. 构造器参数传递

基本构造器参数传递

class Person(val name: String, var age: Int) {
    println(s"Person构造器: name=$name, age=$age")
}

// 子类继承父类属性
class Student(name: String, age: Int, val studentId: String) extends Person(name, age) {
    println(s"Student构造器: studentId=$studentId")
}

object Test {
    def main(args: Array[String]): Unit = {
        val student = new Student("张三", 20, "S001")
        println(s"姓名: ${student.name}, 年龄: ${student.age}, 学号: ${student.studentId}")
    }
}

2. 方法重写(Override)的详细用法

必须使用 override 的情况

class Animal {
    def sound(): String = "动物发出声音"
    
    // 被 final 修饰的方法不能被子类重写
    final def breathe(): String = "呼吸"
}

class Cat extends Animal {
    // 重写父类方法必须使用 override
    override def sound(): String = "喵喵喵"
    
    // 下面的代码会编译错误,因为 breathe 是 final 的
    // override def breathe(): String = "猫呼吸"
}

class Dog extends Animal {
    override def sound(): String = "汪汪汪"
}

3. 字段重写

val 字段的重写

class Shape {
    val description: String = "这是一个形状"
    def area: Double = 0.0
}

class Circle(radius: Double) extends Shape {
    // 重写父类的 val 字段
    override val description: String = "这是一个圆形"
    
    // 重写父类的 def 方法为 val 字段
    override val area: Double = math.Pi * radius * radius
}

object FieldOverride {
    def main(args: Array[String]): Unit = {
        val circle = new Circle(5.0)
        println(circle.description)  // 这是一个圆形
        println(s"面积: ${circle.area}")  // 面积: 78.53981633974483
    }
}

4. 抽象类和抽象方法

抽象类的定义和继承

// 抽象类
abstract class Vehicle {
    // 抽象字段(没有初始化值)
    val brand: String
    
    // 抽象方法(没有方法体)
    def start(): Unit
    
    // 具体方法
    def stop(): Unit = {
        println(s"$brand 停止运行")
    }
}

// 实现抽象类
class Car extends Vehicle {
    // 实现抽象字段
    override val brand: String = "丰田"
    
    // 实现抽象方法
    override def start(): Unit = {
        println(s"$brand 汽车启动")
    }
}

class Bicycle extends Vehicle {
    override val brand: String = "凤凰"
    
    override def start(): Unit = {
        println(s"$brand 自行车开始骑行")
    }
    
    // 可以重写具体方法
    override def stop(): Unit = {
        println(s"$brand 自行车停下")
    }
}

5. 多层级继承

多层继承关系

// 第一层:抽象类
abstract class Employee(val name: String, val salary: Double) {
    def work(): Unit
    def getInfo(): String = s"姓名: $name, 薪资: $salary"
}

// 第二层:具体类
class Developer(name: String, salary: Double, val programmingLanguage: String) 
    extends Employee(name, salary) {
    
    override def work(): Unit = {
        println(s"$name 正在用 $programmingLanguage 编程")
    }
    
    override def getInfo(): String = {
        s"${super.getInfo()}, 编程语言: $programmingLanguage"
    }
}

// 第三层:具体类的子类
class SeniorDeveloper(name: String, salary: Double, programmingLanguage: String, val level: String)
    extends Developer(name, salary, programmingLanguage) {
    
    override def work(): Unit = {
        println(s"$name ($level) 正在用 $programmingLanguage 进行高级开发")
    }
    
    override def getInfo(): String = {
        s"${super.getInfo()}, 级别: $level"
    }
}

object MultiLevelInheritance {
    def main(args: Array[String]): Unit = {
        val dev = new Developer("李四", 15000.0, "Scala")
        val seniorDev = new SeniorDeveloper("张三", 25000.0, "Scala", "高级")
        
        dev.work()
        println(dev.getInfo())
        
        println("---")
        
        seniorDev.work()
        println(seniorDev.getInfo())
    }
}

6. 类型检查和转换

类型检查和类型转换

class Animal
class Dog extends Animal
class Cat extends Animal

object TypeCheck {
    def main(args: Array[String]): Unit = {
        val animals: Array[Animal] = Array(new Dog, new Cat, new Dog)
        
        animals.foreach { animal =>
            // 类型检查
            if (animal.isInstanceOf[Dog]) {
                // 类型转换
                val dog = animal.asInstanceOf[Dog]
                println("这是一只狗")
            } else if (animal.isInstanceOf[Cat]) {
                println("这是一只猫")
            }
            
            // 模式匹配方式(推荐)
            animal match {
                case _: Dog => println("匹配到狗")
                case _: Cat => println("匹配到猫")
                case _ => println("未知动物")
            }
        }
    }
}

7. 密封类(Sealed Class)

密封类的使用

// 密封类,所有子类必须在同一个文件中定义
sealed abstract class Message
case class TextMessage(content: String) extends Message
case class ImageMessage(url: String) extends Message
case class VoiceMessage(duration: Int) extends Message

object MessageProcessor {
    def processMessage(msg: Message): String = msg match {
        case TextMessage(content) => s"文本消息: $content"
        case ImageMessage(url) => s"图片消息: $url"
        case VoiceMessage(duration) => s"语音消息: ${duration}秒"
        // 编译器会警告是否有未处理的case,因为Message是密封的
    }
    
    def main(args: Array[String]): Unit = {
        val messages = List(
            TextMessage("你好"),
            ImageMessage("http://example.com/image.jpg"),
            VoiceMessage(30)
        )
        
        messages.foreach { msg =>
            println(processMessage(msg))
        }
    }
}

8. 构造器执行顺序验证

构造器执行顺序详细验证

class A {
    val aField: String = {
        println("A: 字段初始化")
        "A字段"
    }
    
    println("A: 构造器开始")
    
    def methodA(): Unit = {
        println("A: 方法调用")
    }
    
    println("A: 构造器结束")
}

class B extends A {
    val bField: String = {
        println("B: 字段初始化")
        "B字段"
    }
    
    println("B: 构造器开始")
    
    override def methodA(): Unit = {
        super.methodA()
        println("B: 重写的方法")
    }
    
    println("B: 构造器结束")
}

object ConstructorOrder {
    def main(args: Array[String]): Unit = {
        println("创建B的实例:")
        val b = new B()
        println("调用方法:")
        b.methodA()
    }
}

这些示例展示了 Scala 中继承机制的高级用法,包括构造器参数传递、字段和方法重写、抽象类、多层级继承、类型检查转换等重要概念。