Kotlin语言中的继承与构造函数(详解)

Posted yzk134144

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Kotlin语言中的继承与构造函数(详解)相关的知识,希望对你有一定的参考价值。

        学习kotlin时,有很多小伙伴无法理解为何有的继承结构父类后面需要加括号,有时候却不用加括号,本篇文章小编将为你们解除这个困惑!顺便为大家详解一下kotlin中的主构造函数和次构造函数。
    首先我们先来了解一下kotlin中的继承:    

        比如我们现在要定义一个Student类,每个学生都有自己的学号和年级,我们在Student类中加入sno和grade字段,同时每个学生又都是人,有自己的年龄和名字而且都会睡觉,如果在Student类中重复定义age和name字段还有sleep()函数的话就显得过于冗余,这时我们就可以让Student类去继承Person类,这样就拥有了Person类中的字段和函数了。
    那么kotlin中如何让Student类继承Person类呢,我们分为两个步骤,首先让Person类可以被继承,第二步就是让Student类继承于Person类。
    这里我们就看到kotlin与java的不同了,在kotlin中,任何一个非抽象类都是默认不可被继承的,相当于java中声明了final关键字。
    接下来我们就让Person类能够被继承,很简单,只需要在类前加入open关键字就好了。如下所示:

open class Person{
		...
}

        第二步就是让Student类继承于Person类,不同于java的extends关键字,kotlin中继承使用的时冒号。写法如下:

class Student : Person() {
		var sno = " "
		val grade = 0
}

        这里就出现了我们刚开始提到的,Person类后面我们加入了一个括号,这里就涉及到了一个规定,子类中的构造函数必须调用父类中的构造函数,这里的括号就是代表Student类(子类)的主构造函数调用Person类(父类)的无参构造函数,每个类默认都有一个不带参数的主构造函数,当然也有特殊情况,当一个类没有显式地定义主构造函数且定义了次构造函数时,那么这个类就是没有主构造函数。(这里我们在文章后面还会再提到)接下来我们就来详细介绍一下kotlin中的主构造函数和次构造函数。

        我们说到每个类都会默认有一个不带参数的主构造函数,当然可以显式地给它指明参数,,主构造函数的特点就是没有函数体,直接定义在类名的后面即可,写法如下:

class Student(val sno : String,val grade : Int) : Person(){
}

        这里我们将学号和年级两个字段都放入主构造函数中,当我们对Student类进行实例化时,必须传入构造函数中要求的所有参数,写法如下:

val student = Student("zk123",6)

        既然主构造函数没有函数体,如果我想在主构造函数中编写一些逻辑怎么办呢?当然有办法,kotlin提供了一个init结构体,所有主构造函数中的逻辑都可以写在里面,写法如下:

class Student(val sno : String,val grade : Int) : Person(){
    init{
        println("sno is $sno")
        println("grade is $grade")
    }
}

        这里简单打印了一下学号和年级的值。

        我们改造一下Person类:

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

        那么子类Student类的主构造函数调用父类Person类的构造函数就可以这样写:

class Student(val sno : String,val grade : Int,name : String,age : Int) : 
        Person(name,age){
}

        注意Student类的构造函数中加入的name和age字段不再声明为val或var,假设声明了val或var会自动成为该类的字段,会导致和父类中的name和age字段发生冲突。接下来创建实例就可以这样写:

val student = Student("zk123",6,"Tom",20)

接下来我们来了解一下次构造函数:

        任何一个类只能有一个主构造函数,但可以有多个次构造函数,次构造函数也可以用于实例化一个类,且次构造函数是有函数体的。

        次构造函数是通过constructor关键字来定义的。

        kotlin中规定,当一个类既有主构造函数又有次构造函数时,所有的次构造函数都必须调用主构造函数(包括间接调用),我们举个例子:

        

class Student(val sno : String,val grade : Int,name : String,age : Int) : 
        Person(name,age){
    constructor(name : String,age : Int) : this("",0,name,age){
    }
    constructor() : this("",0){
    }
}

        这里我们定义了两个次构造函数,第一个次构造函数接收name和age两个字段,并通过this关键字调用了主构造函数;第二个构造函数不接收任何参数,通过this关键字调用了我们定义的第一个次构造函数,由于第一个次构造函数调用了主构造函数,所以第二个次构造函数等于间接调用了主构造函数,所以也是合法的。

        接下来我们创建实例就可以通过次构造函数进行创建,写法如下:

val firstStudent = Student("Dick",20)
val secondStudent = Student()

        接下来我们回到上面说到的特殊情况,当一个类没有显式地定义主构造函数且定义了次构造函数时,那么这个类就是没有主构造函数。那既然这个类没有了主构造函数,那这时次构造函数肯定没办法调用主构造函数,此时就得调用父类的构造函数,写法如下:

class Student : Person{
    constructor(name : String,age : Int) : super(name,age){
    }
}

        细心的同学会发现,这里的Person类后面没有了括号,因为此时的Student没有主构造函数,所以不需要调用在主构造函数中调用Person类的构造函数,即不需要再加括号。

        希望这些对大家能有帮助,有不足欢迎大家补充,本篇也是参考郭神的文献,自己梳理一遍方便复习。

以上是关于Kotlin语言中的继承与构造函数(详解)的主要内容,如果未能解决你的问题,请参考以下文章

Kotlin学习之类与对象继承与构造函数

Kotlin 类与继承

将接口从片段传递到kotlin中的活动

Android 学习之《第一行代码》第三版 笔记Kotlin 继承时的括号到底写不写

如何从片段 KOTLIN 中调用意图 [重复]

Kotlin学习之路:继承