欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Kotlin面向?qū)ο笾R(shí)點(diǎn)講解

 更新時(shí)間:2022年12月02日 09:08:10   作者:z啵唧啵唧  
面向?qū)ο缶幊掏ㄟ^對(duì)事物的抽象,大大的簡(jiǎn)化了程序的開發(fā)難度。我們常用的編程語(yǔ)言:Java、C++、Python都屬于面向?qū)ο缶幊?。Kotlin與java類似,也是一種面向?qū)ο缶幊陶Z(yǔ)言。本文從面向?qū)ο笕齻€(gè)基本特征:封裝、繼承、多態(tài),來闡述一下Kotlin中的面向?qū)ο缶幊?/div>

類和對(duì)象

創(chuàng)建一個(gè)Person類

open class Person {
    /**
     * 姓名
     */
    var name = ""
    /**
     * 年齡
     */
    var age = 0
    /**
     * 人的吃飯方法
     */
    fun eat() {
        print(name + " is eating. He is" + age +"years old.")
    }
}

在main函數(shù)中創(chuàng)建Person對(duì)象,對(duì)字符進(jìn)行賦值,調(diào)用類中的方法

fun main() {
    val p = Person();
    p.name = "張三"
    p.age = 10
    p.eat()
}

注意在Kotlin當(dāng)中創(chuàng)建對(duì)象不需要new關(guān)鍵字

繼承和構(gòu)造函數(shù)

  • 繼承是面向?qū)ο蟮囊淮筇匦?/li>
  • 在Kotlin中和java不同的是,在Koitlin中任何一個(gè)非抽象類都是默認(rèn)不可以被繼承的,就相當(dāng)于在java中給一個(gè)類加上了final關(guān)鍵字
  • 因?yàn)樵谝槐久麨镋ffective Java中的書明確提到,如果一個(gè)類不是專門為了繼承而設(shè)計(jì)的,那么他就應(yīng)該加上final聲明,禁止它可以被繼承,這個(gè)屬于就是編程規(guī)范了
  • 在Kotlin當(dāng)中的抽象類和java并沒有什么區(qū)別
  • 在Kotlin中如果想要一個(gè)類可以被繼承,只需要在這個(gè)類的前面加上open關(guān)鍵字即可
  • 如果一個(gè)類要繼承一個(gè)類的話,在java當(dāng)中使用的是extends關(guān)鍵字,在Kotlin當(dāng)中使用的是 : 這個(gè)關(guān)鍵字,而且父類不僅僅要寫出類名還要帶上一對(duì)括號(hào)
class Student : Person() {
    var sno = ""
    var grade = 0
}

Kotlin中類的主構(gòu)造函數(shù)

每個(gè)類都會(huì)默認(rèn)有一個(gè)不帶參數(shù)的主構(gòu)造函數(shù),但是我們也可以顯示的給他指定參數(shù),主構(gòu)造函數(shù)的特點(diǎn)是沒有函數(shù)體,直接定義在類名的后面即可

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

上面這行代碼就表示Student的主構(gòu)造函數(shù)有兩個(gè)參數(shù),分別是sno和grade

在主構(gòu)造函數(shù)當(dāng)中沒有函數(shù)體,那么我們想要在主構(gòu)造函數(shù)當(dāng)中編寫一些代碼邏輯也是可以的,我們可以通過init結(jié)構(gòu)體來進(jìn)行實(shí)現(xiàn)

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

通過init結(jié)構(gòu)體就可以擴(kuò)展的為主構(gòu)造函數(shù)執(zhí)行一些代碼邏輯

那么子類在繼承父類的時(shí)候,為什么父類名后面要跟上一對(duì)括號(hào)呢,原因是,子類在繼承父類的時(shí)候,子類的構(gòu)造函數(shù)必須調(diào)用父類的構(gòu)造函數(shù),所以子類的主構(gòu)造函數(shù)調(diào)用父類的那個(gè)構(gòu)造函數(shù),就是由這個(gè)()來進(jìn)行指定的.

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

在這里Person類后面一對(duì)空括號(hào)表示Student類的主構(gòu)造函數(shù)在初始化的時(shí)候會(huì)調(diào)用Person類的無參構(gòu)造函數(shù)

次構(gòu)造函數(shù):在Kotlin當(dāng)中,每一個(gè)類只能有一個(gè)主構(gòu)造函數(shù),但是可以有多個(gè)次構(gòu)造函數(shù),次構(gòu)造函數(shù)也可以實(shí)例化一個(gè)類,區(qū)別就是主構(gòu)造函數(shù)沒有函數(shù)體,次構(gòu)造函數(shù)有函數(shù)體

Kotlin規(guī)定,在一個(gè)類當(dāng)中如果同時(shí)存在主構(gòu)造函數(shù)和次構(gòu)造函數(shù)的時(shí)候,所有的次構(gòu)造函數(shù)必須調(diào)用主構(gòu)造函數(shù)(包含間接調(diào)用)

次構(gòu)造函數(shù)通過construtor關(guān)鍵字來進(jìn)行聲明

class Student(val sno: String, val grade: Int, name: String, age: Int) : 
Person(name, age) {
    //次構(gòu)造函數(shù)1:直接調(diào)用本類的主構(gòu)造函數(shù),這個(gè)次構(gòu)造函數(shù)有兩個(gè)參數(shù)分別是nanem和age,然后他在調(diào)用本類的主構(gòu)造函數(shù)的時(shí)候直接實(shí)例化了主構(gòu)造函數(shù)中的sno和grade兩個(gè)參數(shù),然后將自己的name和age傳給了調(diào)用了的主構(gòu)造函數(shù)
    constructor(name: String, age: Int) : this("", 0, name, age){
    }
    //次構(gòu)造函數(shù)2:不接收任何的參數(shù),然后沒有直接調(diào)用本類的主構(gòu)造函數(shù),而是調(diào)用了次構(gòu)造函數(shù)1,相當(dāng)于間接調(diào)用了本類的主構(gòu)造函數(shù)
    constructor() : this("張三", 18)
}

當(dāng)Student類通過上述方式編寫之后,我們就可以使用主構(gòu)造函數(shù)或者此構(gòu)造函數(shù)對(duì)其進(jìn)行實(shí)例化了,那么對(duì)Student類進(jìn)行實(shí)例化的方式就有了三種

//使用主構(gòu)造函數(shù)對(duì)Student類進(jìn)行實(shí)例化
val student1 = Student("123", 1, "張三", 18)
//使用次構(gòu)造函數(shù)1對(duì)Student進(jìn)行實(shí)例化
val student2 = Student("張三", 18)
//使用次構(gòu)造函數(shù)2對(duì)Student進(jìn)行實(shí)例化
val student3 = Student()

還有一種比較特殊的情況,類中只包含次構(gòu)造函數(shù),沒有主構(gòu)造函數(shù),這種情況雖然少見,但是在Kotlin當(dāng)中是允許的,當(dāng)一個(gè)類沒有顯示的定義主構(gòu)造函數(shù)但是定義了次構(gòu)造函數(shù)的時(shí)候,它就是沒有主構(gòu)造函數(shù)的

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

在上面的代碼中,首先Student類后i按沒有顯示的定義主構(gòu)造函數(shù),同時(shí)又定義了次構(gòu)造函數(shù),所以Student類是沒有主構(gòu)造函數(shù)的,因?yàn)闆]有主構(gòu)造函數(shù),所以就不牽扯子類的主構(gòu)造函數(shù)調(diào)用父類的主構(gòu)造函數(shù)這一說,所以說Person類的后面沒有加()

另外,由于沒有主構(gòu)造函數(shù),此構(gòu)造函數(shù)只能直接調(diào)用父類的構(gòu)造函數(shù),所以在次構(gòu)造函數(shù)在調(diào)用方法的時(shí)候?qū)his關(guān)鍵字換成了super關(guān)鍵字

接口

Kotlin當(dāng)中的接口和java當(dāng)中的接口幾乎完全是一致的,接口是用于多態(tài)編程的重要組成部分,java是單繼承語(yǔ)言,但是可以實(shí)現(xiàn)多個(gè)接口,Kotlin中也同樣是這樣

定義一Study接口

interface Study {
    fun  readBooks()
    fun doHomeWork()
}

Student實(shí)現(xiàn)Study接口

class Student : Person(), Study{
    var sno = ""
    var grade = 0
    override fun readBooks() {
        println("讀書")
    }
    override fun doHomeWork() {
        println("做作業(yè)")
    }
}

在java當(dāng)中繼承使用的關(guān)鍵字是extends,實(shí)現(xiàn)使用的是impls關(guān)鍵字,而在Kotlin當(dāng)中繼承和實(shí)現(xiàn)統(tǒng)一使用的是 : ,如果即做了繼承又進(jìn)行了實(shí)現(xiàn),使用,進(jìn)行隔開

在上面的代碼中,Student實(shí)現(xiàn)了Study接口,那么他就必須要實(shí)現(xiàn)Study中的兩個(gè)方法,在Kotlin當(dāng)中使用override關(guān)鍵字來重寫父類或者實(shí)現(xiàn)接口中的方法.

多態(tài)編程的特性

fun main() {
    val student = Student()
    doStudy(student)
}
fun doStudy(study: Study) {
    study.readBooks()
    study.doHomeWork()
}

因?yàn)镾tudent實(shí)現(xiàn)了Study接口,在doStudy方法中,需要傳遞的參數(shù)是Study類型,所以也可以傳遞一個(gè)Student的實(shí)例

還有一點(diǎn)就是在Kotlin當(dāng)中可以對(duì)接口中的抽象方法進(jìn)行默認(rèn)的實(shí)現(xiàn)

interface Study {
    fun  readBooks()
    //在Kotlin的接口中可以對(duì)方法進(jìn)行默認(rèn)實(shí)現(xiàn)
    fun doHomeWork() {
        println("do homework")
    }
}

如果接口中的一個(gè)函數(shù),擁有了函數(shù)體,這個(gè)函數(shù)中的內(nèi)容就是他的默認(rèn)實(shí)現(xiàn),現(xiàn)在一個(gè)類去實(shí)現(xiàn)Study接口的時(shí)候,只會(huì)強(qiáng)制要求實(shí)現(xiàn)readBooks方法,而doHomeWork方法可以自由選擇進(jìn)行實(shí)現(xiàn),不是先是就會(huì)自動(dòng)使用默認(rèn)的實(shí)現(xiàn)邏輯

訪問修飾符

在java當(dāng)中的訪問控制符一種有四種:public,private,protected,defaule(什么都不寫)

在Kotlin當(dāng)中也有四種訪問控制符:public,private,protected和internal,需要使用那種修飾符號(hào)的時(shí)候直接在fun關(guān)鍵字前面進(jìn)行添加即可

private修飾符在java和Kotlin當(dāng)中的作用是一摸一樣的,都表示對(duì)當(dāng)前類的內(nèi)部進(jìn)行可見

public修飾符作用雖然也是一致的,表示對(duì)所有的類都可見,但是在java中default是默認(rèn)項(xiàng),但是在Kotlin當(dāng)中public才是默認(rèn)項(xiàng)

protected關(guān)鍵字在java中表示在該類和該類的子類以及同一包中可見,但是在Kotlin當(dāng)中值表示對(duì)該類和子類可見

Kotlin當(dāng)中拋棄了java中的defualt權(quán)限(同一個(gè)包路徑下可見)而是引入了一種新的權(quán)限internal

internal表示在同一個(gè)模塊中的類可見.比如我們開發(fā)一個(gè)模塊給別人用,但是有一些函數(shù)只允許在模塊的內(nèi)部進(jìn)行調(diào)用,不想暴露給外部,那么就可以將這些函數(shù)用internal關(guān)鍵字進(jìn)行修飾

數(shù)據(jù)類和單例

數(shù)據(jù)類通常需要重寫equals,hashCode,toString方法,其中equals方法用于判斷兩個(gè)數(shù)據(jù)是否相等,hashCode方法是equals方法的配套方法,toString方法用來打印更為清晰的日志,否則數(shù)據(jù)打印出來就是一串地址

在java當(dāng)中就要一一的實(shí)現(xiàn)這些方法

但是在Kotlin當(dāng)中,只需要使用date關(guān)鍵字就可以解決

data class Cellphone(val brand: String, val price: Int)

在上面這行代碼中,我就定義了一個(gè)數(shù)據(jù)類,當(dāng)一個(gè)date關(guān)鍵字放在class前面的時(shí)候,就表明自己希望這個(gè)類是一個(gè)數(shù)據(jù)類,Kotlin會(huì)根據(jù)主構(gòu)造函數(shù)中的參數(shù)幫這個(gè)類將equals,hashCode,toString方法進(jìn)行了重寫,另外當(dāng)一個(gè)類中沒有任何代碼時(shí)候,類的{}可以進(jìn)行省略

接下來就是單例類,單例模式是一種基礎(chǔ)的設(shè)計(jì)模式,當(dāng)我們?cè)陂_發(fā)的過程中,希望某個(gè)類在全局最多只能有一個(gè)實(shí)例,這樣就可以使用單例模式,單例模式使用java語(yǔ)言的編寫方式有很多種,雖然簡(jiǎn)單,但是在Kotlin中還有更加簡(jiǎn)單的方法

在Kotlin當(dāng)中創(chuàng)建一個(gè)單例類十分簡(jiǎn)單,只需要將class關(guān)鍵字改成object關(guān)鍵字即可,在創(chuàng)建類的時(shí)候直接選擇object不要選擇class即可

object Singleton {
}

現(xiàn)在Singleton就已經(jīng)是一個(gè)單例類,我們可以直接在這個(gè)類當(dāng)中編寫需要的函數(shù),比如加上一個(gè)singletonTest方法

object Singleton {
    fun singletonTest() {
        println("this is a singleTon.")
    }
}

可以看到在Kotlin當(dāng)中我們不需要私有化構(gòu)造函數(shù),也不需要提供getInstance()這樣的靜態(tài)方法,只需要將class關(guān)鍵字修改該成為object關(guān)鍵字即可

上述代碼在調(diào)用的時(shí)候直接使用Singleton.singletonTest()即可,這種寫法看上去像是靜態(tài)方法調(diào)用,但是實(shí)際上Kotlin在背后自動(dòng)幫我們創(chuàng)建了一個(gè)Singleton類的實(shí)例

到此這篇關(guān)于Kotlin面向?qū)ο笾R(shí)點(diǎn)講解的文章就介紹到這了,更多相關(guān)Kotlin面向?qū)ο髢?nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論