學習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類的建構式,即不需要再加括號,
希望這些對大家能有幫助,有不足歡迎大家補充,本篇也是參考郭神的文獻,自己梳理一遍方便復習,
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/300511.html
標籤:其他
