Kotlin快速入门系列5

本文详细介绍了Kotlin中的类继承机制,包括默认继承Any类、open关键字的使用、构造函数的初始化、重写方法和属性、以及覆盖规则。还展示了如何通过super关键字在子类中选择性地调用基类的方法。
摘要由CSDN通过智能技术生成

Kotlin的继承与重写

kotlin的继承

Kotlin中所有类都继承自Any类,Any类是所有类的超类,对于没有超类型声明的类是默认超类(Any 不是 java.lang.Object):

class LearnKotlin  // 默认继承自Any

Any类默认提供三个函数

equals()

hashCode()

toString()

在kotlin中,除抽象类外的一个类可被继承要在class前添加open关键字进行修饰:

open class BaseClass(p: Int)           // 定义基类

class ExtendsClass(p: Int) : BaseClass(p)

构造函数

1、子类有主构造函数

如果子类有主构造函数,则基类必须在主构造函数中立即初始化。示例如下:

open class Person(name : String, age : Int){

}

class Student(name : String, age : Int, var grade : String, var score : Int) : Person(name, age) {

}

2、子类无主构造函数

如果子类无主构造函数,则必须在每一个次构造函数中用 super 关键字初始化基类,或者在代理另一个构造函数。初始化基类时,可以调用基类的不同构造方法。

class Student : Person {

    constructor(ctx: Context) : super(ctx) {
    }

    constructor(ctx: Context, attrs: AttributeSet) : super(ctx,attrs) {
    }
}

验证实例如下,先构造一个只有次构造函数的基类:

open class Person(name:String){
    /**次级构造函数**/
    constructor(name:String,age:Int):this(name){
        //初始化
        println("-------基类次级构造函数---------")
    }
}

再构造一个继承基类的子类,同时修改子类的次构造函数:

class Student:Person {
    constructor(name:String,age:Int,grade:String,score:Int):super(name, age){
        println("姓名: ${name}")
        println("年龄: ${age}")
        println("年纪: ${grade}")
        println("分数: ${score}")
    }
}

实例化Student对象,即刻看到打印信息:

fun main(args: Array<String>) {
    var student =  Student("Jack", 18, "13", 89)
}

控制台打印信息如下:

重写

在基类里,使用fun声明函数时,默认此函数有final修饰,不能被子类重写。如果想要这个方法可以被重写覆盖,就需要用open字段修饰这方法,同时在重写的方法前必须使用override修饰。如果没有使用open修饰,则子类不允许命名相同名字的函数。

class NetConfig : Base() {

    override fun draw() {   // 前面声明override
        super.draw()
    }

}

open class Base {

    open fun draw() {}  //前面声明open
}

属性覆盖

和重写方法一样,需要重写的属性要用到open这个关键字,同时重写的属性需要用override来修饰。如果没有open来修饰属性,则子类不允许命名相同名字的属性:

open class Person{
    open val num : Int = 0
}
class Student: Person() {
    override var num = 10
}

这里要注意的是,你重写覆盖属性时,可以用一个var属性覆盖val属性,但反过来则不行。(一个val属性本质上是声明了一个get方法,而将其覆盖为 var 只是在子类中额外声明一个 set 方法,反之不行)。

当然,也可以直接在构造函数里覆盖属性:

open class Person{
    open val num : Int = 0
}
class Student(override var num: Int = 0): Person() {
}

覆盖规则

在kotlin中,如果基类有多个相同的方法(继承或者实现自其他类,如A、B类),则必须要重写该方法,使用super范型去选择性地调用基类的实现:

open class A {
    open fun f () { println("A") }
    fun a() { println("a") }
}

interface B {
    fun f() { println("B") } //接口的成员变量默认是 open 的
    fun b() { println("b") }
}

class C() : A() , B{
    override fun f() {
        super<A>.f()//调用 A.f()
        super<B>.f()//调用 B.f()
    }
}

fun main(args: Array<String>) {
    val c =  C()
    c.f()
}

对应命令控制台输出如下:

由程序中可见,C 继承自 A 或 B, C 不仅可以从 A 或者 B 中继承函数,而且 C 可以继承 A()、B() 中共有的函数。

End,如有问题请留言。

  • 13
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值