在 Kotlin 中,类的继承 和方法重载 需要明确使用 open
关键字,因为 Kotlin 默认所有类和方法都是 final
(不可继承/不可重写)。以下是详细规则和示例:
一、类的继承
-
默认不可继承
Kotlin 的类默认是
final
,无法被继承。需用open
标记类才能允许继承。kotlinopen class Animal(val name: String) // 允许被继承 class Dog(name: String) : Animal(name) // 正确
ckotlinCopy Code class Plant // 默认 final,无法被继承 // class Flower : Plant() // 编译错误:Plant 是 final 的
-
继承语法
子类必须调用父类的构造器(主构造器或次构造器)。
kotlinopen class Parent class Child : Parent() // ✅ 正确(调用无参构造器)
二、方法重载
-
默认不可重写
方法默认是
final
,需用open
标记允许子类重写。kotlinopen class Animal { open fun speak() { // 允许被重写 println("...") } } class Dog : Animal() { override fun speak() { // 必须用 override println("Woof!") } }
-
禁止重写
子类中可用
final
禁止进一步重写:kotlinclass Cat : Animal() { final override fun speak() { println("Meow!") } } class Kitten : Cat() { // override fun speak() // 编译错误:speak 是 final 的 }
类与方法重载案例
kotlin
open class Person(private val name:String){
private fun showName() = "父类的姓名是:$name"
open fun printlnName() = println("$name")
}
class Student(private val subName:String):Person(subName){
private fun showName() = "子类 的姓名是【${subName}】"
override fun printlnName() = println(showName())
}
fun main(){
val student = Student("张三")
student.printlnName()
}
三、属性的重写
-
**
open
属性**属性(
val
/var
)也可用open
允许重写:kotlinopen class Shape { open val vertices: Int = 0 } class Triangle : Shape() { override val vertices: Int = 3 }
-
**
val
重写为var
**可以将父类的
val
重写为子类的var
:kotlinopen class Base { open val value: Int = 0 } class Derived : Base() { override var value: Int = 1 // ✅ 允许 }
四、多层继承中的 open
-
父类的方法被重写后,默认仍是
open
的,可用final
关闭:kotlinopen class A { open fun foo() {} } open class B : A() { final override fun foo() {} // 禁止 B 的子类重写 foo } class C : B() { // override fun foo() // 编译错误:foo 是 final 的 }
五、常见错误
-
**忘记
open
**kotlinclass Parent { // 默认 final fun method() {} // 默认 final } class Child : Parent() { // ❌ 编译错误:Parent 不可继承 override fun method() {} // ❌ 编译错误:method 不可重写 }
-
**忘记
override
**kotlinopen class Parent { open fun method() {} } class Child : Parent() { fun method() {} // ❌ 编译错误:缺少 override }
六、与 abstract
的区别
-
abstract
类默认是open
的,无需显式标记:kotlinabstract class AbstractBase { abstract fun mustOverride() // 必须被重写 }
总结
- **
open
**:标记类/方法/属性允许被继承或重写。 - **
override
**:强制要求显式标记重写的成员。 - **
final
**:在子类中禁止进一步重写。