摘要:項目實戰教程第章擴展函數與屬性在使用的時候,我們經常使用諸如等等一堆工具類,代碼寫起來也比較冗長。本章我們介紹的擴展函數和屬性。擴展函數中提供了非常簡單使用的擴展函數功能。
《Kotlin 項目實戰教程》
第6章 擴展函數與屬性
在使用Java的時候,我們經常使用諸如StringUtil, DateUtil等等一堆工具類,代碼寫起來也比較冗長。舉個例子,獲取一個字符串的第一個字符值、最后一個字符值。如果我們用Java代碼來寫,通常是要先聲明一個StringUtil類,然后在里面寫相應的工具方法,代碼可以是下面的這個樣子
package com.easy.kotlin; import static java.lang.System.out; public class StringUtil { /** * 獲取str的第一個字符值 * * @param str * @return */ public static String firstChar(String str) { if (str != null && str.length() > 0) { return str.charAt(0) + ""; } return ""; } /** * 獲取str的最后一個字符值 * * @param str * @return */ public static String lastChar(String str) { if (str != null && str.length() > 0) { return str.charAt(str.length() - 1) + ""; } return ""; } public static void main(String[] args) { String str = "abc"; out.println(StringUtil.firstChar(str)); // a out.println(StringUtil.lastChar(str)); // c } }
我們可以看到 StringUtil.firstChar(str) 這樣的調用方式不夠簡單直接。能不能直接這樣調用
"abc".firstChar() "abc".lastChar()
非常遺憾的是,在Java中我們無法給String類添加一個自定義方法。因為String類是JDK中內置的基礎類,而且為final,不能修改。所以,Java程序員通常使用這樣的一個變通的方法:開發一個StringUtil類,在里面封裝所需要的String操作的方法。而不是修改或繼承String類。
而情況到了Kotlin里面,就完全不一樣了——我們完全可以自由擴展任何類的方法和屬性。在不修改原類的情況下, Kotlin能給一個類擴展新功能而無需繼承該類。
本章我們介紹Kotlin的擴展函數和屬性。
6.1 擴展函數Kotlin中提供了非常簡單使用的擴展函數功能。我們可以為現有的類自由添加自定義的函數 。
6.1.1 給String類擴展兩個函數例如,我們現在給String類擴展兩個函數:lastChar() 和 firstChar() , 實現代碼如下
package com.easy.kotlin fun String.lastChar(): String { if (this.length == 0) { return "" } return this[this.length - 1].toString() } fun String.firstChar(): String { if (this.length == 0) { return "" } return this[0].toString() }
擴展函數的語法,我們用下圖來簡單說明
然后,我們就可以在代碼中直接調用了
fun main(args: Array) { val str = "abc" println(str.firstChar()) // a println(str.lastChar()) // c }
如果在其他package路徑下面,需要 import 導入擴展函數
package com.easy.kotlin.tutorial // 跟擴展函數不在同一個包路徑下面 import com.easy.kotlin.firstChar // 導入擴展函數 firstChar import com.easy.kotlin.lastChar// 導入擴展函數 lastChar fun main(args: Array6.1.2 給 List 類擴展一個過濾函數) { val str = "abc" str.firstChar() // 這樣的調用方式要比 StringUtil.firstChar(str) 簡單優雅許多 str.lastChar() }
在上一章中我們介紹過List的filter函數。那么這個 filter 函數是怎樣實現的呢? 如果我們自己來給List類擴展一個過濾函數,應該怎樣去做呢?下面我們就來介紹。
為了更加深刻體會到 Kotlin 擴展功能的簡單優雅性,我們先來看看在Java中是怎樣實現的吧!首先,我們會去聲明一個ListUtil 類,里面實現一個 List
public class ListUtil{ /** * 根據謂詞p 過濾 list 中的元素 * * @param list * @param p * @return */ public List filter(List list, Predicate p) { List result = new ArrayList<>(); for (T t : list) { if (p.predicate(t)) { result.add(t); } } return result; } }
其中,Predicate 接口聲明如下
interface Predicate{ Boolean predicate(T t); }
然后,我們在代碼中這樣使用這個 filter 方法
public static void main(String[] args) { Listlist = Arrays.asList(new Integer[] {1, 2, 3, 4, 5, 6, 7}); ListUtil listUtil = new ListUtil(); // 聲明ListUtil對象 List result = listUtil.filter(list, (it) -> it % 2 == 1); // lambda 表達式 out.println(result); // [1, 3, 5, 7] }
為了調用 filter 方法,我們還要聲明一個ListUtil對象,費事。能不能直接像下面這樣調用?
list.filter { it % 2 == 1 }
答案是肯定的,只不過是在Kotlin中,而不是在Java中。
我們就來使用Kotlin的擴展函數為List擴展一個filter函數,代碼如下
funList .filter(predicate: (T) -> Boolean): MutableList { val result = ArrayList () this.forEach { if (predicate(it)) { result.add(it) } } return result }
這個函數的簽名稍微有點復雜,我們用下圖來形象化地簡單說明
然后,我們在代碼中只需要這樣調用即可
val list = mutableListOf(1, 2, 3, 4, 5, 6, 7) val result = list.filter { it % 2 == 1 } println(result) // [1, 3, 5, 7]
Kotlin的標準庫API中使用擴展的功能,通過擴展Java的API,提供了大量的實用簡單的函數。我們將在后面的關于文件IO、正則表達式、多線程等相關主題中介紹。
6.2 擴展屬性除了擴展一個類的函數,我們還可以擴展類屬性。例如,我們給 MutableList 擴展兩個屬性:firstElement 和 lastElement , 實現代碼如下
varMutableList .firstElement: T get() { return this[0] } set(value) { this[0] = value } var MutableList .lastElement: T get() { return this[this.size - 1] } set(value) { this[this.size - 1] = value }
上面的代碼中的擴展屬性的語法說明如下圖所示
然后,我們就可以在代碼中直接使用擴展的屬性了
val list = mutableListOf(1, 2, 3, 4, 5, 6, 7) println("list = ${list}") // list = [1, 2, 3, 4, 5, 6, 7] println(list.firstElement) // 調用getter 函數 , 值是 1 println(list.lastElement) // 7 list.firstElement = -1 // 調用 setter 函數 list.lastElement = -7 println("list = ${list}") // list = [-1, 2, 3, 4, 5, 6, -7] println(list.firstElement) // -1 println(list.lastElement) // -7
擴展屬性允許定義在類或者kotlin文件中,不允許定義在函數中。
6.3 擴展中的this關鍵字我們有注意到,在上面的List的擴展函數filter的實現中,我們有用到一個this關鍵字
this.forEach { if (predicate(it)) { result.add(it) } }
這里的 this 指的是 接收者對象(receiver object), 也就是調用擴展函數時, 在點號( . )之前指定的對象實例。
本章小結文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/67765.html
摘要:下一代服務端開發下一代服務端開發第部門快速開始第章快速開始環境準備,,快速上手實現一個第章企業級服務開發從到語言的缺點發展歷程的缺點為什么是產生的背景解決了哪些問題為什么是的發展歷程容器的配置地獄是什么從到下一代企業級服務開發在移動開發領域 《 Kotlin + Spring Boot : 下一代 Java 服務端開發 》 Kotlin + Spring Boot : 下一代 Java...
摘要:于是我就先把這本薄的經典書語言精粹修訂版豆瓣讀書本書簡介總共章,除去附錄,才頁,讀完并記錄了一些筆記。讀書筆記還可以分享給別人看。編程語言第版定義了的標準。程序檢查時丟棄值為函數的屬性。 之前看到這篇文章,前端網老姚淺談:怎么學JavaScript?,說到怎么學習JavaScript,那就是看書、分析源碼。10本書讀2遍的好處,應該大于一本書讀20遍。看書主動學習,看視頻是被動學習。看...
摘要:最近讀完編寫可維護的,讓我受益匪淺,它指明了編碼過程中,需要注意的方方面面,在團隊協作中特別有用,可維護性是一個非常大的話題,這本書是一個不錯的起點。擴展閱讀編寫可維護的歡迎來到石佳劼的博客,如有疑問,請在原文評論區留言,我會盡量為您解答。 最近讀完《編寫可維護的JavaScript》,讓我受益匪淺,它指明了編碼過程中,需要注意的方方面面,在團隊協作中特別有用,可維護性是一個非常大的話...
摘要:設計方案的容易改變這就是所謂的軟件構建的可維護性,可擴展性和靈活性。這也可能表明類型或方法可能難以維護。基于源代碼中不同運算符和操作數的數量的合成度量。對修改的封閉這種模塊的源代碼是不可侵犯的。 大綱 軟件維護和演變可維護性度量模塊化設計和模塊化原則OO設計原則:SOLIDOO設計原則:GRASP總結 軟件維護和演變 什么是軟件維護? 軟件工程中的軟件維護是交付后修改軟件產品以糾正故障...
摘要:第二種接口的概念和面向對象編程相關接口視為一份合約,在合約里可以定義這份合約的類或接口的行為接口告訴類,它需要實現一個叫做的方法,并且該方法接收一個參數。 定場詩 八月中秋白露,路上行人凄涼; 小橋流水桂花香,日夜千思萬想。 心中不得寧靜,清早覽罷文章, 十年寒苦在書房,方顯才高志廣。 前言 洛伊安妮·格羅納女士所著的《學習JavaScript數據結構與算法》第三版于2019年的5月份...
閱讀 3223·2021-11-23 09:51
閱讀 1030·2021-08-05 09:58
閱讀 663·2019-08-29 16:05
閱讀 971·2019-08-28 18:17
閱讀 3029·2019-08-26 14:06
閱讀 2721·2019-08-26 12:20
閱讀 2154·2019-08-26 12:18
閱讀 3064·2019-08-26 11:56