Kotlin的继承

QuibblerQuibbler 2020-06-11 约 8 分钟 2109 次阅读

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最简单的入门教程——类和继承

相关推荐

Parcelize:Parcelable 实现生成器
Kotlin

Parcelize:Parcelable 实现生成器

Parcelize:Parcelable 实现生成器Parcelable是安卓开发中常用的序列化方式,之前分享过一个Parcelable序列化插件,方便开发者快速生成代码,提高开发效率。1、Parcelize插件Kotlin官方也推出一个Parcelable自动生成的Gradle插件:Parcelize。1.1、引入插件在项目的build.gradle中添加:id("kotlin-parceliz

2.6k
 Kotlin基本语法
Kotlin

Kotlin基本语法

Kotlin基本语法了解Kotlin语言的基本语法。1、包kotlin文件以.kt结尾,编译文件还是如此只不过在文件名后面加上Kt后缀。这一点和Java不同,Java源文件.java,编译后为.class文件。1.1、包定义每个kotlin文件的第一行就用关键字package定义该文件所在的包。例:1.2、导包用到其它kotlin文件需要使用关键字import导入,这一点和Java一样。kotli

2.1k
Kotlin循环语句
Kotlin

Kotlin循环语句

Kotlin循环语句每门语言都要学一下循环语句,虽然每种语言都有for、while等循环,但总有些各自的特色。1、for循环for循环遍历集合或者数组,使用 in 关键字遍历任何提供迭代器。语法:例:先定义一个数组或集合array:遍历集合array:通常还需要用到索引index,调用集合的withIndex()方法参与循环遍历。例:使用下面的方式遍历for循环,同时获取元素当前索引index和当

2.1k