Kotlin基礎二

稀飯_發表於2018-06-11

內容:

  • 函式的呼叫方試,過載方消除靜態方法靜態屬性
  • 給別的類擴充套件函式擴充套件屬性
  • 區域性函式和擴充套件
  • 集合建立集合的一些擴充套件特性
  • 字串的一些擴充套件特性

一函式

上一篇我們簡單介紹瞭如何宣告一個函式,這裡我們介紹一下函式呼叫方式函式的過載 和java的區別;

1.1函式的呼叫方式

宣告一個函式 

fun setName(name: String) {
}複製程式碼

在java中我們直接呼叫

setName("張三")複製程式碼

而在kotlin中我們還可以顯示出引數的名字,像這樣

setName(name = "張三")複製程式碼

這樣的好處是,我們看到一個方法,會更加快速的清楚這個引數的意思,可讀性會更強。

1.2函式的過載

在java中如果引數多少不一樣,我們每次都要寫一堆同名方法,像這樣:

fun setName(name: String) {
}

fun setName(name: String, age: Int) {
    
}複製程式碼

而在kotlin我們可以通過設定,來通過一個方法去表現出來過載,替換成這樣:

fun setName(name: String, age: Int = 1) {

}複製程式碼

而呼叫一個引數的時候,並不會報錯。

注意:當你這樣寫過載函式,你會遇到一個再java中呼叫的問題,這時候需要使用@JvmOverloads註解去註解一下你Kotlin中的方法,這樣就能在java中隨意呼叫任何引數的過載方法。像這樣

#Kotlin程式碼
class Dog{
    @JvmOverloads
    fun setName(name: String, age: Int = 1) {
    }
}
複製程式碼

#java中呼叫,沒有問題
Dog dag = new Dog();
dag.setName("222");複製程式碼

1.3 消除靜態方法

java作為一門物件導向的語言,需要所有的程式碼都寫在類內。而kotlin可以把方法寫到類外邊,雖然編譯的時候還是編譯到類內,但是,這種呈現方式更加簡潔:
package utils

fun aa(name: String): String {
    return name
}

複製程式碼

Kotlin中呼叫:

val aa = utils.aa("張三")
Log.e("rrrrr",aa)複製程式碼

java中呼叫:

utils.DogKt.setName("張三");複製程式碼

延伸:同理,宣告在類外邊的訂層屬性,可以做為靜態屬性。像這個值就會被儲存到一個靜態的欄位中。但是這種頂層方法和頂層屬性一般用作靜態工具類,比如單例的時候就不能這樣寫。後邊會講單例。

二 擴充套件函式和擴充套件屬性

2.1擴充套件函式:可以理解成它就是一個類的成員函式,不過定義在類的外面。但必須結合頂層函式去擴充套件。
package utils

fun String.lastChareee(): Char {
    return this.get(this.length-1)
}複製程式碼

呼叫

Log.e("rrrrrrr", "Kotlin".lastChareee().toString())複製程式碼

2.2 java程式碼中呼叫擴充套件函式

實質上,擴充套件函式是靜態函式的語法糖。我們在java中像呼叫靜態方法一樣去呼叫

utils.DogKt.lastChareee("Kotlin");複製程式碼

2.3 擴充套件函式的靜態性質也決定了擴充套件函式不能被子類重寫。但可以被子類繼承。

open class Father

class Son1:Father()

package utils

import android.util.Log
import xifuyin.tumour.com.a51ehealth.kotlin_book.Father

fun Father.setName(){
    Log.e("rrrr","呼叫父類的方法")
}複製程式碼

這時,子類也可以呼叫setName方法。

可以給基類和子類都分別定義一個同名的擴充套件函式,當這個函式被呼叫時,它會用到哪一個呢?

新增子類擴充套件程式碼如下:

package utils

import android.util.Log
import xifuyin.tumour.com.a51ehealth.kotlin_book.Father
import xifuyin.tumour.com.a51ehealth.kotlin_book.Son1

fun Father.setName(){
    Log.e("rrrr","呼叫父類的方法")
}
fun Son1.setName(){
    Log.e("rrrr","呼叫子類的方法")
}複製程式碼

這個時候呼叫:

var s :Father= Son1()
s.setName()

var s = Son1()
s.setName()複製程式碼

呼叫的方法確是不一樣的。

它是由該變數的靜態型別所決定的,而不是這個變數的執行時型別。


注意:如果一個類的成員函式和擴充套件函式有相同的簽名,那麼將會呼叫類的才成員方法。

2.4擴充套件屬性

我們上一篇已經知道,屬性的宣告預設都是提供get和set方法的,所以我們擴充套件屬性,還是要依賴內部的方法。基本沒有什麼用。我也不會。。。。

三 區域性函式和擴充套件

      對於java而言,只有區域性變數,沒有區域性方法,也就是方法中不能再寫方法。在kotlin中方法內可以寫方法,這個內部方法叫做區域性方法。

我們去請求一個資料,要求兩個引數都不能是空字串,我們可以這樣寫

open class Father(var name: String, var address: String) {}複製程式碼
fun save2(fa: Father) {

    fun validate(value: String): Boolean {
        if (value.isEmpty()) {
            Log.e("rrrr", "內部函式")
            return false
        }
        return true
    }

    if (validate(fa.name) && validate(fa.address)) {
        Log.e("rrrr", "外部函式")
        //請求資料
    }

}複製程式碼
這樣程式碼功能性更更加整體,而不會變得零散難讀。

近一步改變,如下:

open class Father(var name: String, var address: String) {}

fun Father.validate(): Boolean {
    fun validate2(value: String): Boolean {
        if (value.isEmpty()) {
            Log.e("rrrr", "內部函式")
            return false
        }
        return true
    }

    return validate2(name) && validate2(address)
}複製程式碼

使用起來更加具有可讀性:

var f = Father("", "")
if (f.validate()) {

}複製程式碼

在Kotlin中集合

4.1集合的建立

在第一篇中我們簡單瞭解了建立list集合和set集合,這裡我們更進一步去了解集合的建立和特性。 kotlin中的集合類和java中的集合類是一樣的,並且提供了簡單的建立方式:

    建立java.util.Arrays$ArrayList集合 : var cc = listOf<String>("aa", "bb")

    建立java.util.ArrayList集合: var cc = arrayListOf<String>("aa", "bb")

    建立java.util.LinkedHashSet集合: var aa = setOf<String>("aa", "bb")

    建立java.util.HashSet集合: var bb = hashSetOf<String>("bb", "aa")

    建立java.util.Collections$SingletonMap集合:val mapOf = mapOf(1 to "one")

    建立java.util.HashMap集合:val map=hashMapOf(1  to “one”)

注意to並不是一個特殊的結構,而是一個普通函式。

4.2 集合的擴充套件特性

儘管Kotlin的集合類和Java的集合類完全一致,但Kotlin提供了更多操作集合的方法:

var cc = listOf<Int>(1, 2)
cc.last()//獲取集合中最後一個資料
cc.max()//獲取集合中最大的一個數複製程式碼
我們感興趣的是它是怎麼工作的:儘管它們是Java庫類的例項,為什麼在Kotlin中能對集合有這麼多豐富的操作。現在答案很明顯了:因為函式last和max都被宣告成了擴充套件函式。你可能會想知道,在Kotlin標準庫中學習所有內容的最佳方式。這個並沒有必要,在你需要操作集合或任何其他物件的時候,根據提示,會展示給你所有可用的函式,包括成員函式和擴充套件函式。

4.3.讓函式支援任意多引數

public fun <T> arrayListOf(vararg elements: T): ArrayList<T>
        = if (elements.size == 0) ArrayList() else ArrayList(ArrayAsCollection(elements, isVarargs = true))複製程式碼

這是arrayListOf方法的內部擴充套件實現,這裡有一個關鍵字vararg,這個關鍵之表示這個引數是可變化的。

private fun add(vararg a: Int) {

}複製程式碼

這個方法就是可以傳遞任意多的引數。

4.4map中的to函式解釋

程式碼中的單詞to不是內建的結構,而是一種特殊的函式呼叫,被稱為中綴呼叫。

在中綴呼叫中,沒有新增額外的分隔符,函式名稱是直接放在目標物件名稱和引數之間的。
以下兩種呼叫方式是等價的:
1.to("one")
1 to "one"複製程式碼
中綴呼叫可以與只有一個引數的函式一起使用,無論是普通的函式還是擴充套件函式。要允許使用中綴符號呼叫函式,需要使用infix修飾符來標記它。下面是一個簡單的to函式的宣告:

infix fun Any.to(other:Any)=Pair(this,other) 複製程式碼

看到這裡,你應該知道to的內部實現原理,還是建立一個pair物件。

五.字串的一些擴充套件特性

Kotlin字串與Java字串完全相同。Kotlin通過提供一系列有用的擴充套件函式,使標準Java字串使用起來更加方便。

5.1分割字串

val split = "12.345-6.A".split("\\.".toRegex())複製程式碼

這是後列印出來結果:[12, 345-6, A]

注意,你可以指定字元引數,並寫入“12.345-6.A".split(‘.’,'-'),一起去分割。

小結:

1.函式的可以使用顯示變數和隱試變數去呼叫

2.函式的過載只需要設定一個,其餘的引數可以設定成預設值,和java互動使用@JvmOverloads去註解

3.函式的靜態寫法,寫到類外邊,不用花括號包裹

4.函式的擴充套件,實質就是靜態語法糖的提現

5.擴充套件的函式子類可以繼承,但不能重寫,呼叫哪個要看生命的靜態型別

6.區域性函式的寫法和使用

7.常用集合的建立

8.集合的擴充套件方法to

9.字串的分割.的問題的解決,和分割方法的過載


相關文章