继承:子类(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
}