原文: https://beginnersbook.com/2019/03/kotlin-inheritance/

继承是一个函数,使用该函数继承另一个类的所有函数。从中继承要素的类称为基类或超类或父类,并且继承要素的类称为派生类或子类或子类。在本指南中,我们将借助示例了解什么是继承以及如何在 Kotlin 中实现它。

什么是继承以及为什么需要它?

假设我们有三个类DogCatHorse。所有这三个类都有一些属性(数据成员)和一些行为(成员函数)。我们在下图中描述了这些类的属性和行为。

Kotlin 继承 - 图1

我们可以在图中看到这三个类具有很少的属性和行为,为什么不创建具有公共属性和行为的泛化类,让这三个类继承该泛化类。此外,除了继承的类之外,这些类可以具有其独特的属性和行为。

Kotlin 继承 - 图2

所以Dog类现在继承了Animal类的所有函数,并添加了一个额外的函数woof(),同样Cat类继承了Animal类的所有函数,并添加了它的独特函数meow()等等。

让我们在 Kotlin 程序中写下这个逻辑。

注意:默认情况下,Kotlin 中的所有类都是最终的,所以你必须在父类中使用open注释,这告诉编译器这个类可以被其他类继承。

  1. open class Animal(colour: String, age: Int) {
  2. init {
  3. println("Color is: $colour.")
  4. println("Age is: $age")
  5. }
  6. }
  7. class Dog(colour: String, age: Int): Animal(colour, age) {
  8. fun woof() {
  9. println("Dog makes sound of woof")
  10. }
  11. }
  12. class Cat(colour: String, age: Int): Animal(colour, age) {
  13. fun meow() {
  14. println("Cat makes sound of meow")
  15. }
  16. }
  17. class Horse(colour: String, age: Int): Animal(colour, age) {
  18. fun neigh() {
  19. println("Horse makes sound of neigh")
  20. }
  21. }
  22. fun main(args: Array<String>) {
  23. val d = Dog("Black",4)
  24. d.woof()
  25. val c = Cat("White", 1)
  26. c.meow()
  27. val h = Horse("Brown", 8)
  28. h.neigh()
  29. }

输出:

Kotlin 继承 - 图3

覆盖 Kotlin 中的成员函数和属性

如果子类中存在具有相同名称的函数或属性,则我们需要使用override关键字在子类中覆盖它们。

覆盖成员函数

子类可以使用override关键字覆盖父类的成员函数。通过重写函数,子类为现有的基类代码提供自己的实现。覆盖并不意味着它将更新基类中的代码,该更改仅适用于覆盖函数或其子类的类。让我们举个例子。

  1. open class Animal() {
  2. open fun sound() {
  3. println("Animal makes a sound")
  4. }
  5. }
  6. class Dog: Animal() {
  7. override fun sound() {
  8. println("Dog makes a sound of woof woof")
  9. }
  10. }
  11. fun main(args: Array<String>) {
  12. val d = Dog()
  13. d.sound()
  14. }

输出:

  1. Dog makes a sound of woof woof

覆盖基类的属性(数据成员)

我们可以覆盖基类的属性,类似于我们在上面看到的成员函数。在下面的示例中,我们在父类中有一个属性颜色,我们在子类中重写它。

  1. open class Animal() {
  2. open var colour: String = "White"
  3. }
  4. class Dog: Animal() {
  5. override var colour: String = "Black"
  6. fun sound() {
  7. println("Dog makes a sound of woof woof")
  8. }
  9. }
  10. fun main(args: Array<String>) {
  11. val d = Dog()
  12. d.sound()
  13. println("${d.colour}")
  14. }

输出:

  1. Dog makes a sound of woof woof
  2. Black

从子类调用基类的数据成员和成员函数

在下面的示例中,我们使用super关键字从Child类调用父类的数据成员num和成员函数demo()

  1. open class Parent() {
  2. open var num: Int = 100
  3. open fun demo(){
  4. println("demo function of parent class")
  5. }
  6. }
  7. class Child: Parent() {
  8. override var num: Int = 101
  9. override fun demo() {
  10. super.demo()
  11. println("demo function of child class")
  12. }
  13. fun demo2(){
  14. println(super.num)
  15. }
  16. }
  17. fun main(args: Array<String>) {
  18. val obj = Child()
  19. obj.demo()
  20. obj.demo2()
  21. }

输出:

  1. demo function of parent class
  2. demo function of child class
  3. 100