Kotlin的继承

Quibbler 2020-6-11 740

Kotlin的继承

        


1、超类:Any

        类似于Java中的Object类,Kotlin也有一个叫Any的超类,是所有类的父类,所有类都默认继承自该类。超类的定义如下,其中定义了三个函数:

package kotlin
/**
 * The root of the Kotlin class hierarchy. Every Kotlin class has [Any] as a superclass.
 */
public open class Any {
    public open operator fun equals(other: Any?): Boolean
    public open fun hashCode(): Int
    public open fun toString(): String
}



2、open

        注意上面的Any类用open修饰,表示该类可以被继承。Kotlin中的类默认都是final的,无法被继承:


        如果想让类可以被继承,就需要用在定义类的地方用open关键字标识该类可以被继承。

//父类open,可以被继承
open class Base {
    //
}

//继承上面的类
class Sub : Base() {
    //
}



3、构造器

        继承中涉及到的子类和父类构造器调用。关于类的构造器参考《类和对象》


3.1、父类无主构造器


3.1.1、无次构造器

        子类只需调用父类的无参构造器即可。

        ①在子类的主构造器处调用

open class Base {
}
//调用父类的默认无参构造器
class Sub : Base() {
}

        ②在子类的次级构造器中调用:

open class Base {
}

class Sub : Base {
    constructor() : super() {
        //子类次级构造器
    }
}


3.1.2、有次级构造器

        ①无参次级构造器

//父类有次级构造器
open class Base {
    constructor() {
        
    }
}

//在子类的次级构造器调用父类的次级构造器
class Sub : Base {
    constructor() : super() {
    }
}

//在子类的主级构造器调用父类的次级构造器
class Sub : Base() {
}

        ②有参次级构造器

open class Base {
    var num: Int
    constructor(num: Int) {
        this.num = num
    }
}

//在子类主构造器中调用父类有参次级构造器
class Sub(num:Int) : Base(num) {
}

//子类次级构造器调用父类有参次级构造器
class Sub : Base {
    constructor(num: Int) : super(num) {
    }
}


3.2、父类有主构造器


3.2.1、父类无参主构造器

        相当于与 3.1.1

open class Base() {
}

//调用父类无参主构造器
class Sub : Base() {
}


3.2.2、父类有参主构造器

        ①子类主构造器中调用父类主构造器

open class Base(var num: Int) {
}

class Sub(num: Int) : Base(num) {
}

        ②子类次级构造器中调用父类主构造器

open class Base(var num: Int) {
}

class Sub : Base {
    constructor(num: Int) : super(num) {
    }
}


注意:

        下面这样的写法编辑器没有报错


        但是运行是会报错:
        Kotlin: Explicit 'this' or 'super' call is required. There is no constructor in superclass that can be called without arguments



4、重写

        使用fun定义函数的时候,函数默认都是final的,不能被继承重写。


4.1、重写父类方法

        想要子类能够继承重写该方法,用open关键字修饰这个函数。

open class Base {
    open fun make() {
        //子类能够重写需要加open修饰
    }
}

class Sub : Base() {
    override fun make() {
        //必须加上override修饰,表示重写父类方法
    }
}


4.2、调用父类方法

        ①通过super调用父类的方法

open class Base {
    open fun make() {
        println("Base")
    }
}

class Sub : Base(){
    override fun make() {
        super.make() //调用父类Base的make()方法
    }
}

        ②如果从父类通过继承获得了两个相同前面的函数,需要指定。

        定义一个类和一个接口,它们都有一个签名一样的方法make()

open class Base {
    open fun make() {
        println("Base")
    }
}

open interface OtherBase {
    open fun make() {
        println("OtherBase")
    }
}

        直接用super调用是不行的。  


        需要明确指定调用哪一个父类的方法,使用super<父类>.fun,调用指定哪一个父类的方法。

class Sub : Base(), OtherBase {
    override fun make() {
        super<Base>.make()
    }
}



5、属性重写

        使用open修饰符标识属性可以被子类重写

open class Base {
    open val num: Int = -1
        get() = field
}

        在子类中使用override

class Sub : Base() {
    override var num: Int = 1
}

        val修饰的父类属性可以被子类修改为var修饰。

        var修饰的父类属性,不能被子类修改为val


        java继承Kotlin父类,只能通过getter/setter访问Kotlin父类中的成员变量。

        而Kotlin继承自Kotlin父类,那么可以直接访问Kotlin父类中的非私有成员变量。



6、抽象类

        使用关键字abstract修饰抽象类和抽象成员。不需要再用open修饰。

abstract class Animal {
    abstract fun getType()
}

        类可以继承声明为抽象的类,并实现其中的方法。

class Dog : Animal() {
    override fun getType() {
    }
}



参考资料:

        Kotlin 继承

        Kotlin中级篇(四):继承类详解

        Kotlin最简单的入门教程——类和继承


不忘初心的阿甘
最新回复 (0)
    • 安卓笔记本
      2
        登录 注册 QQ
返回
仅供学习交流,切勿用于商业用途。如有错误欢迎指出:fluent0418@gmail.com