Kotlin 继承 #

一、继承基础 #

1.1 默认不可继承 #

Kotlin 类默认是 final 的,不能被继承:

kotlin
class Parent  // 等同于 final class

// class Child : Parent()  // 错误:不能继承

1.2 open 关键字 #

使用 open 关键字允许类被继承:

kotlin
open class Parent

class Child : Parent()

1.3 继承语法 #

kotlin
open class Person(val name: String)

class Student(name: String, val grade: Int) : Person(name)

二、方法重写 #

2.1 open 方法 #

kotlin
open class Animal {
    open fun sound() {
        println("Animal sound")
    }
}

class Dog : Animal() {
    override fun sound() {
        println("Woof!")
    }
}

val dog = Dog()
dog.sound()  // Woof!

2.2 final override #

防止方法被进一步重写:

kotlin
open class Animal {
    open fun sound() { }
}

open class Dog : Animal() {
    final override fun sound() {
        println("Woof!")
    }
}

// class Puppy : Dog() {
//     override fun sound() { }  // 错误:不能重写 final 方法
// }

2.3 调用父类方法 #

kotlin
open class Animal {
    open fun sound() {
        println("Animal sound")
    }
}

class Dog : Animal() {
    override fun sound() {
        super.sound()  // 调用父类方法
        println("Woof!")
    }
}

三、属性重写 #

3.1 基本语法 #

kotlin
open class Parent {
    open val name: String = "Parent"
}

class Child : Parent() {
    override val name: String = "Child"
}

3.2 在构造函数中重写 #

kotlin
open class Parent {
    open val name: String = "Parent"
}

class Child(override val name: String) : Parent()

3.3 val 与 var #

kotlin
open class Parent {
    open val name: String = "Parent"
}

// val 可以重写为 var
class Child : Parent() {
    override var name: String = "Child"
}

// var 不能重写为 val

四、抽象类 #

4.1 定义抽象类 #

kotlin
abstract class Animal {
    abstract fun sound()
    
    fun sleep() {
        println("Sleeping...")
    }
}

class Dog : Animal() {
    override fun sound() {
        println("Woof!")
    }
}

4.2 抽象属性 #

kotlin
abstract class Shape {
    abstract val area: Double
    abstract val perimeter: Double
    
    fun describe(): String {
        return "Area: $area, Perimeter: $perimeter"
    }
}

class Rectangle(val width: Double, val height: Double) : Shape() {
    override val area: Double
        get() = width * height
    
    override val perimeter: Double
        get() = 2 * (width + height)
}

4.3 抽象类继承 #

kotlin
abstract class Vehicle {
    abstract val speed: Int
    abstract fun move()
}

abstract class Car : Vehicle() {
    override fun move() {
        println("Driving at $speed km/h")
    }
}

class Sedan(override val speed: Int) : Car()

五、接口继承 #

5.1 实现接口 #

kotlin
interface Flyable {
    fun fly()
}

interface Swimmable {
    fun swim()
}

class Duck : Flyable, Swimmable {
    override fun fly() {
        println("Flying")
    }
    
    override fun swim() {
        println("Swimming")
    }
}

5.2 解决冲突 #

kotlin
interface A {
    fun foo() { println("A") }
}

interface B {
    fun foo() { println("B") }
}

class C : A, B {
    override fun foo() {
        super<A>.foo()  // 调用 A 的实现
        super<B>.foo()  // 调用 B 的实现
        println("C")
    }
}

六、类型检查与转换 #

6.1 is 操作符 #

kotlin
open class Animal
class Dog : Animal()
class Cat : Animal()

fun identify(animal: Animal) {
    when (animal) {
        is Dog -> println("It's a dog")
        is Cat -> println("It's a cat")
        else -> println("Unknown animal")
    }
}

6.2 智能类型转换 #

kotlin
open class Animal {
    open fun sound() { }
}

class Dog : Animal() {
    fun bark() { println("Woof!") }
}

fun makeSound(animal: Animal) {
    if (animal is Dog) {
        animal.bark()  // 智能转换为 Dog
    }
}

6.3 as 操作符 #

kotlin
val animal: Animal = Dog()

// 不安全转换
val dog = animal as Dog

// 安全转换
val cat = animal as? Cat  // null

七、多态 #

7.1 运行时多态 #

kotlin
open class Shape {
    open fun draw() {
        println("Drawing shape")
    }
}

class Circle : Shape() {
    override fun draw() {
        println("Drawing circle")
    }
}

class Square : Shape() {
    override fun draw() {
        println("Drawing square")
    }
}

fun render(shape: Shape) {
    shape.draw()  // 运行时决定调用哪个方法
}

render(Circle())  // Drawing circle
render(Square())  // Drawing square

7.2 多态集合 #

kotlin
val shapes = listOf<Shape>(Circle(), Square(), Circle())

shapes.forEach { it.draw() }

八、实战示例 #

8.1 图形层次结构 #

kotlin
abstract class Shape(val name: String) {
    abstract fun area(): Double
    abstract fun perimeter(): Double
    
    fun describe(): String {
        return "$name: area=${area()}, perimeter=${perimeter()}"
    }
}

class Rectangle(val width: Double, val height: Double) : Shape("Rectangle") {
    override fun area() = width * height
    override fun perimeter() = 2 * (width + height)
}

class Circle(val radius: Double) : Shape("Circle") {
    override fun area() = Math.PI * radius * radius
    override fun perimeter() = 2 * Math.PI * radius
}

val shapes = listOf(
    Rectangle(3.0, 4.0),
    Circle(5.0)
)

shapes.forEach { println(it.describe()) }

8.2 员工系统 #

kotlin
abstract class Employee(val name: String, val id: Int) {
    abstract fun calculateSalary(): Double
    
    fun displayInfo() {
        println("ID: $id, Name: $name, Salary: ${calculateSalary()}")
    }
}

class FullTimeEmployee(
    name: String,
    id: Int,
    private val baseSalary: Double
) : Employee(name, id) {
    override fun calculateSalary() = baseSalary
}

class PartTimeEmployee(
    name: String,
    id: Int,
    private val hourlyRate: Double,
    private val hoursWorked: Int
) : Employee(name, id) {
    override fun calculateSalary() = hourlyRate * hoursWorked
}

val employees = listOf(
    FullTimeEmployee("Alice", 1, 5000.0),
    PartTimeEmployee("Bob", 2, 20.0, 80)
)

employees.forEach { it.displayInfo() }

九、最佳实践 #

9.1 组合优于继承 #

kotlin
// 不推荐:深层继承
open class Animal
open class Mammal : Animal
open class Dog : Mammal

// 推荐:使用组合
class Dog(
    private val movement: Movement,
    private val sound: Sound
)

9.2 使用接口定义行为 #

kotlin
// 推荐
interface Drawable {
    fun draw()
}

interface Clickable {
    fun click()
}

class Button : Drawable, Clickable {
    override fun draw() { }
    override fun click() { }
}

9.3 标记不应继承的类 #

kotlin
// 不应被继承的类
class Constants {
    companion object {
        const val MAX_SIZE = 100
    }
}

// 或使用 final 显式标记
final class Utility

十、总结 #

继承要点:

关键字 用途
open 允许类/方法被继承/重写
override 重写父类方法/属性
abstract 抽象类/方法
super 调用父类实现
is 类型检查
as 类型转换

下一步,让我们学习 接口

最后更新:2026-03-27