0Pricing
Scala for Backend Engineering & Functional Programming · 课时

继承与多态

探索 Scala 中的面向对象原则,例如继承、抽象类和多态。

继承与多态 是 CoddyKit 上的免费 Scala for Backend Engineering & Functional Programming 课时。 这是第 2 节课,共 2 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Scala for Backend Engineering & Functional Programming 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Scala for Backend Engineering & Functional Programming 课程共包含 2 节课。

什么是继承?

继承是面向对象编程(OOP)中的一个基本概念,它允许新类从已有类继承属性和行为(方法)。

您可以把它想象成“父子”关系。“子”类(子类)会复用“父”类(超类)中的代码,从而节省时间并确保一致性。

  • 促进代码复用。
  • 建立“是一个”的关系(例如,Dog 是一个 Animal)。
  • 帮助将代码组织成层次结构。

您的第一个基类

让我们定义一个简单的 Animal 类。它将作为我们的基类,也称为超类或父类。它具有一个基本行为:speak。

运行代码,看看我们的通用动物如何工作!

class Animal {
  val name: String = "Generic Animal"
  def speak(): Unit = {
    println(s"$name makes a sound.")
  }
}

object Main {
  def main(args: Array[String]): Unit = {
    val myAnimal = new Animal()
    myAnimal.speak()
  }
}

使用 `extends` 扩展

现在,让我们创建一种更具体的动物:Dog。Dog 是一个 Animal,因此可以使用 extends 关键字从 Animal 类继承。

我们还可以重写 speak 方法,让 Dog 发出自己独特的声音。请注意 override 关键字。

class Animal {
  val name: String = "Generic Animal"
  def speak(): Unit = {
    println(s"$name makes a sound.")
  }
}

class Dog extends Animal {
  override val name: String = "Dog"
  override def speak(): Unit = {
    println(s"$name barks!")
  }
}

object Main {
  def main(args: Array[String]): Unit = {
    val myAnimal = new Animal()
    val myDog = new Dog()
    myAnimal.speak() // Generic Animal makes a sound.
    myDog.speak()    // Dog barks!
  }
}

`override` 的作用

在 Scala 中,override 关键字非常重要,原因如下:

  • 清晰性:它明确告诉其他开发者,此方法或字段正在替换超类中的相应成员。
  • 安全性:编译器会检查您是否确实在重写现有成员。如果您拼写错误,或超类中的方法发生变化,编译器会提醒您。
  • 意图:它清楚地表明了您要专门化或更改继承行为的意图。

重新定义继承的成员时,请始终使用 override!

多态:多种形式

多态的意思是“多种形式”。在面向对象编程中,它允许将不同类的对象作为某个共同超类的对象来处理。

这意味着您可以拥有一个 Animal 类型的变量,而它保存的可以是 Dog 对象、Cat 对象,或 Animal 的任何其他子类对象。当您对该变量调用方法时,实际对象类型所对应的正确方法会被执行。

  • 支持灵活且可扩展的代码。
  • 为不同的数据类型提供统一的接口。
  • 通过方法重写实现。

实践中的多态

让我们看看多态的实际效果。我们将创建一个类似于 Dog 的 Cat 类。然后,可以将不同类型的动物放入其共同超类型 Animal 的列表中,并调用它们的 speak 方法。

请注意,尽管列表中的所有对象都被视为 Animal 类型,但每种动物都会以自己独特的方式发声。

class Animal {
  val name: String = "Generic Animal"
  def speak(): Unit = {
    println(s"$name makes a sound.")
  }
}

class Dog extends Animal {
  override val name: String = "Dog"
  override def speak(): Unit = {
    println(s"$name barks!")
  }
}

class Cat extends Animal {
  override val name: String = "Cat"
  override def speak(): Unit = {
    println(s"$name meows!")
  }
}

object Main {
  def main(args: Array[String]): Unit = {
    val animals: List[Animal] = List(
      new Animal(),
      new Dog(),
      new Cat()
    )

    animals.foreach(_.speak())
  }
}

介绍抽象类

有时,您希望基类定义一个通用接口,但不为其中一些成员提供完整的实现。这正是抽象类的用途。

抽象类:

  • 不能直接实例化(您不能创建抽象类的对象)。
  • 可以包含抽象方法(没有实现的方法)和具体方法(具有实现的方法)。
  • 充当蓝图,其子类必须完成该蓝图。

构建抽象蓝图

让我们定义一个 abstract class Shape。每个形状都有一个面积,但计算面积的公式因具体形状(圆形、矩形等)而异。

因此,我们将 area 声明为抽象方法。请注意,它没有方法体(没有 = { ... })。子类需要负责提供它的实现。

abstract class Shape {
  def area: Double // Abstract method, no implementation
  
  def describe(): Unit = {
    println("This is a geometric shape.")
  }
}

// You cannot do: new Shape() - it's abstract!

object Main {
  def main(args: Array[String]): Unit = {
    println("Abstract class Shape defined.")
    println("Cannot instantiate Shape directly.")
  }
}

具体实现

现在,让我们创建 Circle 和 Rectangle 这样的具体子类,并让它们扩展我们的 abstract class Shape。这些子类必须为抽象的 area 方法提供实现。

它们还会从 Shape 继承具体的 describe() 方法。

abstract class Shape {
  def area: Double
  def describe(): Unit = {
    println("This is a geometric shape.")
  }
}

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

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

object Main {
  def main(args: Array[String]): Unit = {
    val circle = new Circle(5)
    val rectangle = new Rectangle(4, 6)

    println(s"Circle area: ${circle.area}")
    circle.describe()
    println(s"Rectangle area: ${rectangle.area}")
    rectangle.describe()
  }
}

继承与多态检查

以下关于 Scala 中继承和多态的说法哪些是 TRUE?

回顾:继承与多态

做得很好!在本课中,我们学习了 Scala 中面向对象编程的核心概念:

  • 继承:子类如何使用 extends 复用代码,并与超类建立“是一个”的关系。
  • override 关键字:用于明确重定义继承的方法和字段,对确保类型安全和清晰性至关重要。
  • 多态:将不同子类的对象作为共同超类的对象来处理的能力,从而实现灵活且可扩展的代码。
  • 抽象类:不能直接实例化的蓝图,用于定义通用接口和必须由子类实现的抽象成员。

这些概念对于构建结构良好且易于维护的 Scala 应用至关重要!

常见问题解答

「继承与多态」课时是免费的吗?

是的 — 「继承与多态」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Scala for Backend Engineering & Functional Programming 课程的其余内容,请升级到 CoddyKit PRO。 Scala for Backend Engineering & Functional Programming 课程共包含 2 节课。

「继承与多态」这节课中我会学到什么?

探索 Scala 中的面向对象原则,例如继承、抽象类和多态。 你通过在浏览器中直接运行的动手代码来练习 Scala for Backend Engineering & Functional Programming,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Scala for Backend Engineering & Functional Programming 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Scala for Backend Engineering & Functional Programming 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 2 节。

「继承与多态」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Scala for Backend Engineering & Functional Programming 课中编写并运行代码吗?

能。每节 Scala for Backend Engineering & Functional Programming 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 类、对象与打包
  2. 继承与多态
← 返回 Scala for Backend Engineering & Functional Programming