Kotlin 中类的继承与方法重载

在 Kotlin 中,‌类的继承 ‌和‌方法重载 ‌需要明确使用 open 关键字,因为 Kotlin 默认所有类和方法都是 final(不可继承/不可重写)。以下是详细规则和示例:


一、类的继承

  1. 默认不可继承

    Kotlin 的类默认是 final,无法被继承。需用 open 标记类才能允许继承。

    kotlin 复制代码
    open class Animal(val name: String) // 允许被继承
    class Dog(name: String) : Animal(name) // 正确
    c 复制代码
    kotlinCopy Code
    class Plant // 默认 final,无法被继承
    // class Flower : Plant()  // 编译错误:Plant 是 final 的
  2. 继承语法

    子类必须调用父类的构造器(主构造器或次构造器)。

    kotlin 复制代码
    open class Parent
    class Child : Parent() // ✅ 正确(调用无参构造器)

二、方法重载

  1. 默认不可重写

    方法默认是 final,需用 open 标记允许子类重写。

    kotlin 复制代码
    open class Animal {
        open fun speak() { // 允许被重写
            println("...")
        }
    }
    
    class Dog : Animal() {
        override fun speak() { // 必须用 override
            println("Woof!")
        }
    }
  2. 禁止重写

    子类中可用 final 禁止进一步重写:

    kotlin 复制代码
    class 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()
}

三、属性的重写

  1. ‌**open 属性**‌

    属性(val/var)也可用 open 允许重写:

    kotlin 复制代码
    open class Shape {
        open val vertices: Int = 0
    }
    
    class Triangle : Shape() {
        override val vertices: Int = 3
    }
  2. ‌**val 重写为 var**‌

    可以将父类的 val 重写为子类的 var

    kotlin 复制代码
    open class Base {
        open val value: Int = 0
    }
    
    class Derived : Base() {
        override var value: Int = 1 // ✅ 允许
    }

四、多层继承中的 open

  • 父类的方法被重写后,默认仍是 open 的,可用 final 关闭:

    kotlin 复制代码
    open class A {
        open fun foo() {}
    }
    
    open class B : A() {
        final override fun foo() {} // 禁止 B 的子类重写 foo
    }
    
    class C : B() {
        // override fun foo() // 编译错误:foo 是 final 的
    }

五、常见错误

  1. ‌**忘记 open**‌

    kotlin 复制代码
    class Parent { // 默认 final
        fun method() {} // 默认 final
    }
    
    class Child : Parent() { // ❌ 编译错误:Parent 不可继承
        override fun method() {} // ❌ 编译错误:method 不可重写
    }
  2. ‌**忘记 override**‌

    kotlin 复制代码
    open class Parent {
        open fun method() {}
    }
    
    class Child : Parent() {
        fun method() {} // ❌ 编译错误:缺少 override
    }

六、与 abstract 的区别

  • abstract 类默认是 open 的,无需显式标记:

    kotlin 复制代码
    abstract class AbstractBase {
        abstract fun mustOverride() // 必须被重写
    }

总结

  • ‌**open**‌:标记类/方法/属性允许被继承或重写。
  • ‌**override**‌:强制要求显式标记重写的成员。
  • ‌**final**‌:在子类中禁止进一步重写。
相关推荐
zh_xuan1 小时前
Android Looper源码阅读
android
用户02738518402611 小时前
[Android]RecycleView的item用法
android
前行的小黑炭12 小时前
Android :为APK注入“脂肪”,论Android垃圾代码在安全加固中的作用
android·kotlin
帅得不敢出门13 小时前
Docker安装Ubuntu搭建Android SDK编译环境
android·ubuntu·docker
tangweiguo0305198713 小时前
Android Kotlin 动态注册 Broadcast 的完整封装方案
android·kotlin
fatiaozhang952713 小时前
浪潮CD1000-移动云电脑-RK3528芯片-2+32G-安卓9-2种开启ADB ROOT刷机教程方法
android·网络·adb·电脑·电视盒子·刷机固件·机顶盒刷机
前行的小黑炭14 小时前
Android 不同构建模式下使用不同类的例子:如何在debug模式和release模式,让其使用不同的类呢?
android·kotlin·gradle
andyguo14 小时前
AI模型测评平台工程化实战十二讲(第一讲:从手工测试到系统化的觉醒)
android
2501_9159214314 小时前
小团队如何高效完成 uni-app iOS 上架,从分工到工具组合的实战经验
android·ios·小程序·uni-app·cocoa·iphone·webview
幂简集成15 小时前
通义灵码 AI 程序员低代码 API 课程实战教程
android·人工智能·深度学习·神经网络·低代码·rxjava