Kotlin 中的继承与实现

继承:子类(Subclass)继承父类(Superclass)的属性和方法,用于代码复用和多态,关键词是 : 父类()(只能有一个)。

实现:类实现接口(Interface)的抽象方法,用于定义行为规范,关键词是: 接口(可多个)。

Kotlin 对继承做了严格限制:所有类默认是 final 的(不可继承),必须显式用 open 修饰才能被继承;接口默认是 open 的且接口中的方法默认是 open/abstract 的。

1 继承

1.1 基础语法
kotlin 复制代码
// 1. 父类:必须用 open 修饰才能被继承
open class Animal(
    val name: String,
    val age: Int
) {
    // 父类方法:默认 final,用 open 修饰才能被重写
    open fun makeSound() {
        println("$name 发出声音")
    }

    open fun eat() {
        println("$name 吃东西")
    }
}

// 2. 子类:继承 Animal,用 : 父类(构造参数)
class Dog(name: String, age: Int, val breed: String) : Animal(name, age) {
    // 重写父类方法:必须用 override 修饰
    override fun makeSound() {
        println("$name ($breed) 汪汪叫")
    }
}

// 3. 使用
fun main() {
    val dog = Dog("旺财", 3, "哈士奇")
    dog.makeSound()     // 旺财 (哈士奇) 汪汪叫
    dog.eat()           // 旺财 吃东西
}
1.2 继承的关键规则
  • 构造函数调用: 子类必须在声明处或主构造函数中调用父类的构造函数(Animal(name, age));
  • 重写限制:
    • 父类方法/属性必须加 open 才能被重写;
    • 子类重写必须加 override(不可省略);
    • 重写后的方法默认是 open 的,若想禁止子类再重写,加 final
  • 属性重写: 不仅方法,属性也能重写(需父类属性加 open);
  • 单继承限制: Kotlin 和 Java 一样,一个类只能继承一个父类,避免多继承的菱形问题;

代码示例:

kotlin 复制代码
// 禁止子类再重写
final override fun makeSound() {
  
}

// 属性重写
open class Animal {
    open val legCount: Int = 4
}

class Bird : Animal() {
    override val legCount: Int = 2 // 重写属性值
}

2 实现

2.1 基础实现语法

接口定义行为规范,类实现接口时必须实现其所有抽象方法:

kotlin 复制代码
interface Runnable {
    // 抽象方法(默认 abstract,无需显式声明)
    fun run()

    fun stop() {
        println("停止运行")
    }
}

interface Swimmable {
    fun swim()
}

class Fish : Runnable, Swimmable {
    override fun run() {
        println("鱼靠鳍游动")
    }

    override fun swim() {
        println("鱼在水里游")
    }

    override fun stop() {
        println("鱼静止在水中")
    }

}

// 3. 使用
fun main() {
    val fish = Fish()
    fish.run()      // 输出:鱼靠鱼鳍游动
    fish.swim()     // 鱼在水里游
    fish.stop()     // 鱼静止在水中
}
2.2 接口的关键规则
  • 接口不能有构造函数: 接口无法实例化,只能被类实现;
  • 接口属性: 接口中可声明属性,但只能是抽象的,或提供默认 getter;
  • 多实现冲突: 若实现多个接口且接口有同名默认方法,必须显式重写解决冲突;

代码示例:

kotlin 复制代码
interface Flyable {
    val maxSpeed: Int // 抽象属性,实现类必须重写
    val minSpeed: Int get() = 0 // 默认 getter,实现类可选择重写
}

class Eagle : Flyable {
    override val maxSpeed: Int = 100 // 必须重写抽象属性
    // minSpeed 使用默认值 0,无需重写
}

interface A {
    fun doSomething() = println("A")
}

interface B {
    fun doSomething() = println("B")
}

class C : A, B {
    override fun doSomething() {
        // 显式指定使用哪个接口的实现
        super<A>.doSomething()
        super<B>.doSomething()
        // 或自定义逻辑
        println("C")
    }
}

3 继承 + 实现 混合使用

实际开发中,类通常既继承父类,又实现多个接口:

kotlin 复制代码
// 父类
open class Vehicle(val brand: String) {
    open fun drive() {
        println("$brand 行驶中")
    }
}

// 接口 1
interface Electric {
    fun charge() = println("充电中")
}

// 接口 2
interface Autopilot {
    fun autoDrive()
}

// 子类:继承 Vehicle + 实现 Electric、Autopilot
class Tesla(brand: String) : Vehicle(brand), Electric, Autopilot {

    // 重写父类方法
    override fun drive() {
        println("$brand 电动行驶中")
    }

    // 实现接口的抽象方法
    override fun autoDrive() {
        println("$brand 自动驾驶中")
    }

    // 可选:重写接口默认方法
    override fun charge() {
        println("$brand 超充中(1小时充满)")
    }


}
// 3. 使用
fun main() {
    val tesla = Tesla("特斯拉 Model Y")
    tesla.drive()       // 特斯拉 Model Y 电动行驶中
    tesla.charge()      // 特斯拉 Model Y 超充中(1小时充满)
    tesla.autoDrive()   // 特斯拉 Model Y 自动驾驶中
}

4 抽象类 + 接口 组合

抽象类(abstract class)是"半实现"的类(可包含抽象方法和具体方法),接口是"纯规范":

kotlin 复制代码
// 抽象类:有抽象方法 + 具体方法
abstract class Shape {
    abstract fun calculateAre(): Double // 抽象方法,子类必须实现

    fun printInto() {
        println("面积 ${calculateAre()}")
    }
}

// 接口:定义额外行为
interface Drawable {
    fun draw()
}

// 子类:继承抽象类 + 实现接口
class Circle(val radius: Double) : Shape(), Drawable {
    override fun calculateAre(): Double {
        return Math.PI * radius * radius
    }

    override fun draw() {
        println("绘制圆形,半径: $radius")
    }
}

fun main() {
    val circle = Circle(5.0)
    circle.draw()  // 绘制圆形,半径: 5.0
    circle.printInto() // 面积 78.53981633974483
}
相关推荐
阿巴斯甜8 小时前
Android 报错:Zip file '/Users/lyy/develop/repoAndroidLapp/l-app-android-ble/app/bu
android
Kapaseker9 小时前
实战 Compose 中的 IntrinsicSize
android·kotlin
xq952710 小时前
Andorid Google 登录接入文档
android
黄林晴11 小时前
告别 Modifier 地狱,Compose 样式系统要变天了
android·android jetpack
冬奇Lab1 天前
Android触摸事件分发、手势识别与输入优化实战
android·源码阅读
城东米粉儿1 天前
Android MediaPlayer 笔记
android
Jony_1 天前
Android 启动优化方案
android
阿巴斯甜1 天前
Android studio 报错:Cause: error=86, Bad CPU type in executable
android
张小潇1 天前
AOSP15 Input专题InputReader源码分析
android
_小马快跑_1 天前
Kotlin | 协程调度器选择:何时用CoroutineScope配置,何时用launch指定?
android