继承与抽象类
1. 继承的概念与语法
在 Kotlin 中,继承是面向对象编程的核心特性之一,允许子类继承父类的属性和方法。Kotlin 的继承语法如下:
open class Parent {
// 父类必须标记为 open 才能被继承
}
class Child : Parent() {
// 子类继承父类
}
关键点:
- 所有类默认是
final的,必须显式标记为open才能被继承。 - 继承使用
:符号,父类需要加上构造函数调用()。
2. 方法重写
子类可以重写父类的方法,但父类方法必须标记为 open,子类方法必须标记为 override:
open class Animal {
open fun makeSound() {
println("Some generic animal sound")
}
}
class Dog : Animal() {
override fun makeSound() {
println("Bark!")
}
}
3. 属性重写
与方法类似,属性也可以被重写:
open class Shape {
open val vertexCount: Int = 0
}
class Rectangle : Shape() {
override val vertexCount: Int = 4
}
4. 抽象类
抽象类用于定义不能直接实例化的基类,可以包含抽象成员(没有实现):
abstract class Polygon {
abstract fun draw() // 抽象方法,必须被子类实现
fun printSides() { // 具体方法
println("This polygon has sides")
}
}
class Hexagon : Polygon() {
override fun draw() {
println("Drawing a hexagon")
}
}
抽象类特点:
- 用
abstract关键字声明 - 可以包含抽象方法和具体方法
- 不能直接实例化
- 子类必须实现所有抽象成员
5. 继承中的构造函数
主构造函数继承
open class Base(val name: String)
class Derived(name: String) : Base(name)
次构造函数继承
open class View {
constructor(ctx: Context) { /*...*/ }
constructor(ctx: Context, attr: AttributeSet) { /*...*/ }
}
class MyView : View {
constructor(ctx: Context) : super(ctx)
constructor(ctx: Context, attr: AttributeSet) : super(ctx, attr)
}
6. 继承规则总结
- Kotlin 中所有类默认是 final 的
- 使用
open关键字使类可继承 - 使用
override关键字重写成员 - 抽象类用
abstract声明,可以包含抽象成员 - 一个类只能继承一个父类(单继承)
- 子类必须初始化父类的所有属性
7. 何时使用继承 vs 接口
| 特性 | 继承 | 接口 |
|---|---|---|
| 实现 | 单继承 | 多实现 |
| 状态 | 可以包含属性状态 | 不能包含状态(Kotlin 1.4+可以有属性) |
| 默认实现 | 可以提供方法实现 | 可以提供默认实现 |
| 使用场景 | "是一个"关系 | "具有能力"关系 |
最佳实践: 优先使用接口组合,必要时才使用继承。
示例:完整继承体系
abstract class Employee(val name: String, val salary: Double) {
abstract fun calculateBonus(): Double
}
open class Developer(name: String, salary: Double) : Employee(name, salary) {
override fun calculateBonus() = salary * 0.15
}
class SeniorDeveloper(name: String, salary: Double) : Developer(name, salary) {
override fun calculateBonus() = super.calculateBonus() + 1000
}
这个例子展示了从抽象类到具体类的完整继承链,以及方法重写的实际应用。
