Kotlin 學(xué)習(xí)筆記(四)類黎做、繼承叉跛、重構(gòu)、構(gòu)造函數(shù)蒸殿、接口

SeaCliffBridge_ZH-CN5362667487_1920x1080.jpg

前言
本文章只是用于記錄學(xué)習(xí)筷厘,所以部分地方如果有錯(cuò)誤或者理解不對(duì)的地方,麻煩請(qǐng)指正宏所。本篇為 csdn 原文章 轉(zhuǎn)移修改版 原文章

Kotlin 學(xué)習(xí)筆記(三)

簡述:

  1. kotlin 中接口的簡單使用
  2. kotlin 中 類和屬性的繼承
  3. kotlin 中類的重載函數(shù)
  4. kotlin 中修飾符的介紹
  5. kotlin 中嵌套類 內(nèi)部類的講解
  6. kotlin 的主構(gòu)造函數(shù)和次構(gòu)造函數(shù)

1.接口

相比于 java 的接口酥艳,kotlin 還是有點(diǎn)不同的

1.Kotlin 的接口聲明 默認(rèn)都是 final 和 public 的
2.Kotlin 中的接口 和 java 1.8 接口相似,可以包含 抽象方法的定義 和 非抽象方法的實(shí)現(xiàn)

// 接口
interface Clicker{
    fun click()
}

// 實(shí)現(xiàn)類
class MeButton : Clicker{
    override fun click() {
        println("not implemented")
    }
}

// 調(diào)用
fun main(args: Array<String>) {
    var button:MeButton = MeButton()
    button.click()
}

?? 上述代碼爬骤,我們看到 kotlin 中 使用 “:” 代替了 java 中的 extends 和 implements , 和 java 相同的充石,kotlin 也是單繼承,但是可以實(shí)現(xiàn)多個(gè)接口霞玄。和java 中的 @override 相同骤铃,override 用來注釋 繼承父類的方法,或者 接口的方法或?qū)傩钥谰纾煌氖?kotlin 中的 override 是強(qiáng)制添加上的惰爬,這樣可以避免先寫實(shí)現(xiàn)方法 在添加抽象方法 造成的重寫。
kotlin 接口中可以有默認(rèn)實(shí)現(xiàn)的方法惫企,但是java 中則需要在方法中表明 default 關(guān)鍵字撕瞧,而kotlin中是不用添加 關(guān)鍵字的。

interface Clicker{
    fun click()
    fun staticClick(){
        println("默認(rèn)實(shí)現(xiàn)")
    }
}

?? 如果你 實(shí)現(xiàn)了這個(gè)接口狞尔,你也可以繼承該方法丛版,對(duì)他進(jìn)行修改,當(dāng)然你也可以不實(shí)現(xiàn)該方法偏序。

1.如果 你分別繼承兩個(gè) 接口硼婿,兩個(gè)接口有相同的默認(rèn)實(shí)現(xiàn)函數(shù),如果不顯式的指明調(diào)用哪一個(gè)禽车,運(yùn)行的時(shí)候會(huì)報(bào)錯(cuò)寇漫。
2.解決辦法就是 實(shí)現(xiàn)兩個(gè)接口中相同名稱的函數(shù),在函數(shù)中指明引用殉摔,
2.1 super< AInterface >.click(); super< BInterface >.click(); 而在java中的表達(dá)方式則是 AInterface .super.click(); 表現(xiàn)方式不太一樣

2. 繼承

?2.1 繼承函數(shù)

??java 中的父類默認(rèn)都是 可以繼承的州胳,所以我們?cè)趯?BaseActivity 或者 BaseFragment 的時(shí)候都要慎重的設(shè)計(jì),因?yàn)橐徊恍⌒?就會(huì)讓子類實(shí)現(xiàn)很多沒有的類逸月。所以 kotlin中 的方法默認(rèn)都是 final 栓撞,如果需要子類繼承就要特地標(biāo)記 open 修飾符。

class MeButton : Clicker{
    override fun click() {  // 實(shí)現(xiàn) Clicker 方法 默認(rèn) 為open 可繼承
        println("not implemented")
    }

    fun dieable(){}   // 默認(rèn)為 final

    open fun openClass(){}  // 明確表明 為open 可繼承
}

?? 如果是實(shí)現(xiàn) 基類的方法 或者 接口的方法,默認(rèn)是open 的瓤湘,如果希望改變瓢颅,可以自己添加修飾符 final 。

Kotlin 中所有類都有一個(gè)共同的超類 Any弛说,這對(duì)于沒有超類型聲明的類是默認(rèn)超類

?2.2 繼承屬性

?? 繼承屬性和繼承函數(shù)差不多挽懦,在父類中聲明然后在子類中重新聲明的屬性必須以 override 開頭,并且它們必須具有兼容的類型木人。每個(gè)聲明的屬性可以由具有初始化器的屬性或者具有 getter 方法的屬性覆蓋信柿。
?? 注意: var 屬性可以繼承自一個(gè) val 屬性 ,反之則不可以醒第。(var 屬性不能 讓val 繼承 )

interface Foo {
    val count: Int
}

class Bar1(override val count: Int) : Foo

class Bar2 : Foo {
    override var count: Int = 0
}

?? 上述代碼渔嚷,我們?cè)谥鳂?gòu)造函數(shù)中也可以使用 override 。

?2.3 abstract

我們通過一段代碼 來了解一下 abstract

// 抽象類稠曼,不能創(chuàng)建實(shí)例
abstract class abClas{
    // 抽象方法 默認(rèn)就是open(此處省略) 不能實(shí)例形病,必須繼承實(shí)現(xiàn)
    abstract fun  ab1()
    //抽象類中的 方法 不是默認(rèn)open的,所以需要標(biāo)明
    open fun ab2(){}
    
    fun ab3(){}
}

其他地方和 java 的都比較相似霞幅,這里就不多贅述

2.4 重載函數(shù)

由于在Java中是沒有默認(rèn)值參數(shù)的概念窒朋,當(dāng)我們需要從Java中調(diào)用Kotlin中的默認(rèn)值重載函數(shù)的時(shí)候,必須顯示的指定所有參數(shù)值蝗岖。但是這個(gè)絕對(duì)不是我們想要侥猩,否則Kotlin就失去了重載的意義了不能和Java完全互操作。所以在Kotlin給出了另一個(gè)方案就是使用@JvmOverloads注解這樣就會(huì)自動(dòng)生成多個(gè)重載方法供Java調(diào)用抵赢。

@JvmOverloads
fun <T> joinString(
        collection: Collection<T> = listOf(),
        separator: String = ",",
        prefix: String = "",
        postfix: String = ""
): String {
    return collection.joinToString(separator, prefix, postfix)
}

//調(diào)用的地方
fun main(args: Array<String>) {
    //函數(shù)使用命名參數(shù)可以提高代碼可讀性
    println(joinString(collection = listOf(1, 2, 3, 4), separator = "%", prefix = "<", postfix = ">"))
    println(joinString(collection = listOf(1, 2, 3, 4), separator = "%", prefix = "<", postfix = ">"))
    println(joinString(collection = listOf(1, 2, 3, 4), prefix = "<", postfix = ">"))
    println(joinString(collection = listOf(1, 2, 3, 4), separator = "!", prefix = "<"))
    println(joinString(collection = listOf(1, 2, 3, 4), separator = "!", postfix = ">"))
    println(joinString(collection = listOf(1, 2, 3, 4), separator = "!"))
    println(joinString(collection = listOf(1, 2, 3, 4), prefix = "<"))
    println(joinString(collection = listOf(1, 2, 3, 4), postfix = ">"))
    println(joinString(collection = listOf(1, 2, 3, 4)))
}

3. 修飾符

??和 java 的大多數(shù)修飾符是一樣的欺劳,但是java 默認(rèn)為 private ,但是kotlin 中默認(rèn)為 public 铅鲤,并且 kotlin中沒有 包可見划提,新添加的修飾符為 :internal ,表示只在模塊內(nèi)部可用。

這里寫圖片描述

1.在kotlin 中 public 是不可以訪問 低可見性 internal 的邢享。
2.另外還要注意的是 protected 鹏往,在java 中他的訪問范圍是 包中,但是在kotlin 中則是 局限到 類 或者子類中骇塘,

  1. 類的擴(kuò)展函數(shù) 是訪問不到 private 和 protected 的伊履。

4. 嵌套類 內(nèi)部類

??和java 一樣,kotlin 也是可以在類中 包 類款违,但是 內(nèi)部類是不可以訪問 外部類的屬性的 唐瀑,除非你做 了特殊的 安排。

class MeButton : Clicker {
    private var a: Int = 1
    override fun click() {
        println("not implemented")
    }

    fun dieable() {}

    open fun openClass() {}
    // inner 關(guān)鍵字是重點(diǎn)
    inner class CButton {
        var b: Int = a
    }
}

??從上述代碼中看到插爹,我這里在 類 MeButton 中新添加了一個(gè) 類 CButton 哄辣,如果在沒有添加 inner 的情況下请梢,稱之為 嵌套類,CButton 中是無法獲取到外部類的引用的力穗。
??如果添加上 inner 后毅弧,則算是內(nèi)部類,可以獲取到外部類的引用当窗。

5. 類

??類 不管是 在 java 和 kotlin 中都是比較重要的一部分够坐,前邊的幾張我們也都寫了很多 class 的代碼 ,這里我們?cè)敿?xì)的講解下超全。

// Kotlin 中使用關(guān)鍵字 class 聲明類
class Invoice { ... }

class Empty

?? 類聲明由類名咆霜、類頭 以及由花括號(hào)包圍的類體構(gòu)成邓馒。類頭與類體都是可選的嘶朱; 如果一個(gè)類沒有類體,可以省略花括號(hào)光酣。

?5.1 主構(gòu)造函數(shù)

??Kotlin 中的一個(gè)類可以有一個(gè)主構(gòu)造函數(shù)以及一個(gè)或多個(gè)次構(gòu)造函數(shù)疏遏。主構(gòu)造函數(shù)是類頭的一部分:它跟在類名后

class Person constructor(firstName: String) {  }

class Person (firstName: String) {  }

?上述代碼 就是典型的 構(gòu)造函數(shù)救军,我們可以使用 constructor 關(guān)鍵字來形容财异,當(dāng)然如果該類沒有其他修飾符 可以省略 constructor 不寫。

?5.2 初始化 init

初始化的代碼可以放到以 init 關(guān)鍵字作為前綴的初始化塊中唱遭。

初始化代碼塊

class InitOrderDemo(name: String) {
    
    val secondProperty = "Second property: ${name.length}".also(::println)
    val customerKey = name.toUpperCase()
    val firstProperty = "First property: $name".also(::println)
    init {
        println("First initializer block that prints ${name}")
    }

    
    init {
        println("Second initializer block that prints ${name.length}")
    }
}

// 運(yùn)行代碼
fun main(args: Array<String>) {
    InitOrderDemo("hello")
}

運(yùn)行結(jié)果

Second property: 5
First property: hello
First initializer block that prints hello
Second initializer block that prints 5

??上段代碼我們初步了解了 init 的使用方法戳寸, 主構(gòu)造的參數(shù)可以在初始化塊中使用 或者是 屬性中(val customerKey = name.toUpperCase())。
如果構(gòu)造函數(shù)有注解或可見性修飾符拷泽,這個(gè) constructor 關(guān)鍵字是必需的疫鹊,并且這些修飾符在它前面:

public class Customer @Inject constructor(name: String) { }

?5.3 次構(gòu)造函數(shù)

類也可以聲明前綴有 constructor的次構(gòu)造函數(shù):

class Person {
    // 次 構(gòu)造函數(shù)
    constructor(parent: Person) {
        parent.children.add(this)
    }
}

??如果類有一個(gè)主構(gòu)造函數(shù),每個(gè)次構(gòu)造函數(shù)需要委托給主構(gòu)造函數(shù)司致, 可以直接委托或者通過別的次構(gòu)造函數(shù)間接委托拆吆。委托到同一個(gè)類的另一個(gè)構(gòu)造函數(shù)用 this 關(guān)鍵字即可:

??初始化塊 init 中的代碼實(shí)際上會(huì)成為主構(gòu)造函數(shù)的一部分。委托給主構(gòu)造函數(shù)會(huì)作為次構(gòu)造函數(shù)的第一條語句脂矫,因此所有初始化塊中的代碼都會(huì)在次構(gòu)造函數(shù)體之前執(zhí)行枣耀。即使該類沒有主構(gòu)造函數(shù),這種委托仍會(huì)隱式發(fā)生庭再,并且仍會(huì)執(zhí)行初始化塊

??如果一個(gè) 非 抽象類 沒有聲明 任何 構(gòu)造函數(shù)捞奕,那么 程序會(huì)默認(rèn)生成一個(gè)沒有參數(shù) 可見性為 public 的主構(gòu)造函數(shù),如果你不希望你的類有一個(gè)公有構(gòu)造函數(shù)拄轻,你需要聲明一個(gè)帶有非默認(rèn)可見性的空的主構(gòu)造函數(shù)缝彬。

Kotlin 學(xué)習(xí)筆記(五)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市哺眯,隨后出現(xiàn)的幾起案子谷浅,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,602評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件一疯,死亡現(xiàn)場離奇詭異撼玄,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)墩邀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門掌猛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人眉睹,你說我怎么就攤上這事荔茬。” “怎么了竹海?”我有些...
    開封第一講書人閱讀 152,878評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵慕蔚,是天一觀的道長。 經(jīng)常有香客問我斋配,道長孔飒,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,306評(píng)論 1 279
  • 正文 為了忘掉前任艰争,我火速辦了婚禮坏瞄,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘甩卓。我一直安慰自己鸠匀,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,330評(píng)論 5 373
  • 文/花漫 我一把揭開白布逾柿。 她就那樣靜靜地躺著缀棍,像睡著了一般。 火紅的嫁衣襯著肌膚如雪鹿寻。 梳的紋絲不亂的頭發(fā)上睦柴,一...
    開封第一講書人閱讀 49,071評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音毡熏,去河邊找鬼坦敌。 笑死,一個(gè)胖子當(dāng)著我的面吹牛痢法,可吹牛的內(nèi)容都是我干的狱窘。 我是一名探鬼主播,決...
    沈念sama閱讀 38,382評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼财搁,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼蘸炸!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起尖奔,我...
    開封第一講書人閱讀 37,006評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤搭儒,失蹤者是張志新(化名)和其女友劉穎穷当,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體淹禾,經(jīng)...
    沈念sama閱讀 43,512評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡馁菜,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,965評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了铃岔。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片汪疮。...
    茶點(diǎn)故事閱讀 38,094評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖毁习,靈堂內(nèi)的尸體忽然破棺而出智嚷,到底是詐尸還是另有隱情,我是刑警寧澤纺且,帶...
    沈念sama閱讀 33,732評(píng)論 4 323
  • 正文 年R本政府宣布盏道,位于F島的核電站,受9級(jí)特大地震影響隆檀,放射性物質(zhì)發(fā)生泄漏摇天。R本人自食惡果不足惜粹湃,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,283評(píng)論 3 307
  • 文/蒙蒙 一恐仑、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧为鳄,春花似錦裳仆、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至偏形,卻和暖如春静袖,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背俊扭。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評(píng)論 1 262
  • 我被黑心中介騙來泰國打工队橙, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人萨惑。 一個(gè)月前我還...
    沈念sama閱讀 45,536評(píng)論 2 354
  • 正文 我出身青樓捐康,卻偏偏與公主長得像,于是被迫代替她去往敵國和親庸蔼。 傳聞我的和親對(duì)象是個(gè)殘疾皇子解总,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,828評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容