继承与多态 #

一、继承基础 #

1.1 基本语法 #

使用 extends 关键字:

scala
class Animal(val name: String):
  def speak(): String = "Some sound"

class Dog(name: String) extends Animal(name):
  def fetch(): String = s"$name fetches the ball"

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

1.2 调用父类构造函数 #

scala
class Vehicle(val brand: String, val year: Int)

class Car(brand: String, year: Int, val model: String) 
  extends Vehicle(brand, year):
  def info: String = s"$brand $model ($year)"

val car = Car("Toyota", 2024, "Camry")
println(car.info)

1.3 单继承 #

Scala 只支持单继承:

scala
class A
class B extends A

二、方法重写 #

2.1 override 关键字 #

scala
class Animal:
  def speak(): String = "Some sound"

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

class Cat extends Animal:
  override def speak(): String = "Meow!"

val dog = Dog()
val cat = Cat()
println(dog.speak())
println(cat.speak())

2.2 调用父类方法 #

使用 super 关键字:

scala
class Animal:
  def speak(): String = "Some sound"

class Dog extends Animal:
  override def speak(): String = s"${super.speak()} and Woof!"

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

2.3 重写 val 属性 #

scala
class Parent:
  val name: String = "Parent"

class Child extends Parent:
  override val name: String = "Child"

val child = Child()
println(child.name)

2.4 重写 def 为 val #

scala
class Parent:
  def name: String = "Parent"

class Child extends Parent:
  override val name: String = "Child"

val child = Child()
println(child.name)

三、类型检查与转换 #

3.1 isInstanceOf #

检查对象是否是某个类型的实例:

scala
class Animal
class Dog extends Animal
class Cat extends Animal

val animal: Animal = Dog()

if animal.isInstanceOf[Dog] then
  println("It's a dog")

if animal.isInstanceOf[Cat] then
  println("It's a cat")

3.2 asInstanceOf #

类型转换:

scala
val animal: Animal = Dog()

if animal.isInstanceOf[Dog] then
  val dog = animal.asInstanceOf[Dog]
  println("Converted to Dog")

3.3 模式匹配(推荐) #

scala
def describe(animal: Animal): String = animal match
  case dog: Dog => "It's a dog"
  case cat: Cat => "It's a cat"
  case _ => "Unknown animal"

describe(Dog())
describe(Cat())

3.4 getClass #

获取实际类型:

scala
val animal: Animal = Dog()
println(animal.getClass.getSimpleName)

四、多态 #

4.1 运行时多态 #

scala
abstract class Shape:
  def area: Double

class Circle(val radius: Double) extends Shape:
  override def area: Double = math.Pi * radius * radius

class Rectangle(val width: Double, val height: Double) extends Shape:
  override def area: Double = width * height

def printArea(shape: Shape): Unit =
  println(s"Area: ${shape.area}")

printArea(Circle(5))
printArea(Rectangle(10, 20))

4.2 多态集合 #

scala
val shapes: List[Shape] = List(
  Circle(5),
  Rectangle(10, 20),
  Circle(3)
)

val totalArea = shapes.map(_.area).sum
println(s"Total area: $totalArea")

4.3 方法重载 #

scala
class Calculator:
  def add(a: Int, b: Int): Int = a + b
  def add(a: Double, b: Double): Double = a + b
  def add(a: Int, b: Int, c: Int): Int = a + b + c

val calc = Calculator()
calc.add(1, 2)
calc.add(1.5, 2.5)
calc.add(1, 2, 3)

五、抽象类 #

5.1 定义抽象类 #

scala
abstract class Animal:
  def name: String
  def speak(): String
  
  def info: String = s"$name says: ${speak()}"

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

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

5.2 抽象方法与具体方法 #

scala
abstract class Shape:
  def area: Double
  
  def describe: String = s"Area is $area"

class Circle(val radius: Double) extends Shape:
  override def area: Double = math.Pi * radius * radius

val circle = Circle(5)
println(circle.describe)

5.3 抽象字段 #

scala
abstract class 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)

六、final 和 sealed #

6.1 final 类 #

不能被继承:

scala
final class FinalClass:
  def method: String = "Cannot override"

class SubClass extends FinalClass

6.2 final 方法 #

不能被重写:

scala
class Parent:
  final def cannotOverride: String = "Final method"

class Child extends Parent:
  override def cannotOverride: String = "Error"

6.3 sealed 类 #

只能在同一文件中继承:

scala
sealed trait Animal
case class Dog(name: String) extends Animal
case class Cat(name: String) extends Animal

def describe(animal: Animal): String = animal match
  case Dog(name) => s"Dog: $name"
  case Cat(name) => s"Cat: $name"

七、继承与构造函数 #

7.1 主构造函数继承 #

scala
class Person(val name: String, val age: Int)

class Employee(name: String, age: Int, val salary: Double) 
  extends Person(name, age):
  def info: String = s"$name, $age years old, salary: $salary"

val emp = Employee("Alice", 30, 50000)
println(emp.info)

7.2 辅助构造函数与继承 #

scala
class Person(val name: String, val age: Int):
  def this(name: String) = this(name, 0)

class Employee(name: String, age: Int, val salary: Double) 
  extends Person(name, age):
  def this(name: String) = this(name, 0, 0)

val emp = Employee("Alice")
println(s"${emp.name}, ${emp.age}, ${emp.salary}")

八、继承最佳实践 #

8.1 组合优于继承 #

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

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

8.2 使用 trait 实现多继承 #

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)
    }

8.3 使用 sealed 处理有限情况 #

scala
sealed trait Result[+T]
case class Success[T](value: T) extends Result[T]
case class Failure(message: String) extends Result[Nothing]

def handle(result: Result[Int]): String = result match
  case Success(value) => s"Success: $value"
  case Failure(msg) => s"Error: $msg"

九、总结 #

继承关键字 #

关键字 说明
extends 继承类或 trait
override 重写方法或属性
super 调用父类方法
final 禁止继承或重写
sealed 限制继承范围

类型操作 #

方法 说明
isInstanceOf 类型检查
asInstanceOf 类型转换
getClass 获取类型
模式匹配 安全类型处理

下一步,让我们学习 特质

最后更新:2026-03-27