一、继承

1、Kotlin继承与Java继承的不同之处

  • 在Kotlin中,类并不是生来就能被继承的,只有在类 class关键字前添加 open关键字 的类才可以被继承。之所以这样操作是因为如果一个类不是专门设计来被继承的,那么就很可能出现未知的风险。
  • Kotlin中继承 使用 “”(冒号),而非是extends关键字。
open class Person{
    var name = ""
    var age = 0
}

//Student类继承Person类
class Student:Person(){


}

 


 

二、构造函数

在Kotlin中存在两类构造函数,分别是 主构造函数次构造函数。

1. 主构造函数

特点:

  • 没有函数体
  • 直接定义在类名后面,所需要的参数直接放入括号类
class Student(val s_no:String,val age:Int):Person(){
    ...
}
  • 如果需要在主构造函数中编写逻辑,需要使用 init 结构体
class Student(val s_no:String, val grade:Int):Person(){

    init{
        println("s_no is " + s_no)
        println("grade is "+ grade)
    }
}

 


注:你可能会看着继承的Person后面的那个()不顺眼,这个括号究竟是干什么用的呢?

因为子类中的构造函数必需调用父类中的构造函数,但又因为在Kotlin中,主构造函数是没有函数体的。你当然可以每次都在init结构体中调用,但是在大多数情况下,init结构体是不适用的,而且每次都写会很不方便,所以,这个继承的类后面的()就起到了指明当前类的主构造函数所调用的是父类的哪个构造函数的作用。此处只有一个空的括号,代表调用父类中没有无参的构造函数。

open class Person{
    var name = "空"
    var age = 0
}


class Student:Person(){
    
    var sno = "未设置"
    var grade = 1
}

fun main(){
    
    val s = Student()
    println(s.name)
    println(s.age)
    println(s.sno)
    println(s.grade)
}

 输出结果:

空
0
未设置
1

 


 

  • 主构造函数中声明的 val 或者 var 的参数将自动成为该类的属性(如 Student类的 sno和grade属性),而没有val 或者 var关键字的参数,其作用域仅限于主构造函数内有效(如 Student类的name和age属性)。
open class Person(val name:String, val age:Int){
}


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

}

fun main(){
    
    val s = Student("S0001",1,"Hack",20)
    println(s.name)
    println(s.age)
    println(s.sno)
    println(s.grade)
}

输出结果:

Hack
20
S0001
1

二、次构造函数

一个类可只能有一个主构造函数,但是可以有多个次构造函数。

  • 次构造函数有函数体,并通过 constructor关键字 定义。
  • 当一个类既有主构造函数又有次构造函数时,所有的次构造函数都必须调用主构造函数(包括间接调用)。
open class Person(val name:String, val age:Int){
}


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){
        
    }

}

fun main(){
    
    val s = Student("S0001",1,"Hack",20)
    val s1 = Student("Hack",20)
    val s2 = Student()


}

当类中只有次构造函数,没有显示的定义主构造函数时,就代表该类没有主构造函数的。

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



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

Teacher类没有显示的声明主构造函数(在类名Teacher后没有括号),同时又声明了次构造函数,所以此时的Teacher没有主构造函数。

因为Teacher没有主构造函数,所以继承Person类的时候就不需要在Person后加括号了。

有因为没有主构造函数,所以次构造函数只能调用父类的构造函数,所以 this关键字被换成了 super关键字