? 在關(guān)于Kotlin初體驗中基礎語法基本上已經(jīng)介紹了一遍秘狞,這篇文章主要是對于Kotlin的一些特性的用法和理解算是補充和進階吧氧秘。
Kotlin的修飾符:
Kotlin 的寫法(默認為 public)? ? ? ?作用域:
public:? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 默認摊溶,總是可見
internal:? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 同模塊可見
protected:? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?類似于private,但對子類也可見
private:? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?聲明范圍與同模塊的子作用域可見
在Kotlin初體驗中也提到過Kotlin的空安全,用操作符“?”來明確指定一個對象炼蛤,或者一個屬性變量是否可以為空。
@限定this:
@作為標記蝶涩,可以作為跳出循環(huán)的break或return:
:: 操作符:
?表示把一個方法當做一個參數(shù)鲸湃,傳遞到另一個方法中進行使用赠涮,通俗的來講就是引用一個方法
需要注意test 函數(shù)的第三個參數(shù)傳入 tests 時,要確定這個參數(shù)個數(shù)暗挑、類型笋除、返回值都一致。
引用其他類中的方法只需要在::操作符前加上需要調(diào)用的方法的對象
集合:
Kotlin沒有自己的集合API而是直接調(diào)用Java原有的集合,不過Kotlin優(yōu)化了集合的操作
data關(guān)鍵字:
在kotlin中 data 修飾符 相當于 java中 public 炸裆、 getter?垃它、 setter ?、 toString 等的集合.
@JvmOverloads方法自動重載:
$符號在kotlin中表示引用某個參數(shù)烹看,類似于java中的%s
擴展方法:
之前在初體驗這篇文章提到過kotlin的一大特色擴展方法国拇,拓展方法可以在任何地方為已有類進行方法的拓展,拓展之后的方法使用和原生方法一致惯殊。
引用一下官方描述:
Kotlin, similar to C# and Gosu, provides the ability to extend a class with new functionality without having to inherit from the class or use any type of design pattern such as Decorator. This is done via special declarations called extensions. Kotlin supports extension functions and extension properties.
意思就是Kotlin無需通過繼承或裝飾器模式酱吝,即可為特定類擴展出新的函數(shù)和屬性.
舉個例子以Toast為例,生成一個Toast需要我們傳入三個參數(shù)土思,其中最關(guān)鍵的就是Context上下文對象务热,因為創(chuàng)建窗口需要建立在上下文的基礎上才能完成,因此我們通常需要寫一個Toast的工具來來方便我們使用己儒,但是有了拓展方法之后就能在任意Context子類下直接調(diào)用我們拓展的方法崎岂。
在Java中”萬物皆為對象“,所有的方法和屬性都是基于類存在的闪湾,但是很多類都是封裝好的冲甘,如果需要對它進行拓展的話就必須對它進行繼承,這樣會加大了我們的復雜性和耦合性.這就是Kotlin引入擴展方法的原因吧.
擴展方法實際上就是一個對應Java中的靜態(tài)方法途样,這個靜態(tài)方法參數(shù)為接收者類型的對象江醇,然后利用這個對象就可以訪問這個類中的成員屬性和方法了,并且最后返回一個這個接收者類型對象本身何暇。這樣在外部感覺和使用類的成員函數(shù)是一樣的嫁审。
擴展方法不能被重寫
根據(jù)測試結(jié)果顯示擴展方法并不是類的一部分,盡管子類和父類擁有了相同的擴展方法. 從測試來看赖晶,子類和父類擁有了相同的擴展方法律适,實際上就是定義兩個同名的靜態(tài)擴展方法分別傳入父類和子類,那么調(diào)用的方法肯定也是父類中的方法和子類中的方法遏插,所以輸出肯定是父類的.
因為拓展方法的原理是基于靜態(tài)函數(shù)的捂贿,所以不符合面向?qū)ο蟮囊?guī)則。簡單說就是胳嘲,它不管最終生成的是什么對象厂僧,它只關(guān)心系統(tǒng)識別出來是什么對象,只會按照引用的類型來調(diào)用了牛。
協(xié)程:
先簡單介紹一下什么是協(xié)程,很多人對這個詞很陌生.其實協(xié)程就是被認為可暫停計算的實例颜屠,即可以在某些點暫停并稍后可能在另一個線程上恢復執(zhí)行的協(xié)程辰妙。協(xié)同程序相互呼叫(以及來回傳遞數(shù)據(jù))可以形成協(xié)作式多任務處理的機制。
簡單來說就是協(xié)程是一種“輕量級線程“甫窟,從Kotlin 1.1開始引入密浑。由于一些耗時操作(如網(wǎng)絡IO、文件 IO粗井、CPU或GPU密集型任務)會使線程阻塞直到操作完成尔破,協(xié)程提供了一種避免線程阻塞、開銷更小且更加可控的異步操作浇衬。
添加 dependencies :
示例:
咦launch懒构、CommonPool、delay是啥??下面來解釋一下:
launch
launch方法定義在kotlinx.coroutines.experimental
解釋一下launch方法有3個參數(shù):context(上下文)耘擂、start(啟動選項)胆剧、block(真正要執(zhí)行的代碼塊,必須是suspend修飾的方法)
launch方法返回一個Job醉冤,Job是協(xié)程創(chuàng)建的后臺任務的概念秩霍,它持有該協(xié)程的引用。Job繼承自CoroutineContext類型冤灾。一個Job有三種狀態(tài):
New?新建 (初始狀態(tài))
Active? 活動中(默認狀態(tài))
Completed?已結(jié)束(最終狀態(tài))
很明顯可以看出launch方法以非阻塞當前線程的方式,啟動一個新的協(xié)程后臺任務辕近,并返回一個Job對象作為當前協(xié)程的引用韵吨。
CommonPool
CommonPool是共享線程池的意思,它的主要作用是來調(diào)度計算密集型任務的協(xié)程的執(zhí)行移宅。它的實現(xiàn)使用的是java.util.concurrent包下面的API归粉。首先嘗試創(chuàng)建一個java.util.concurrent.ForkJoinPool,如果不可用,就使用java.util.concurrent.Executors來創(chuàng)建一個普通的線程池:Executors.newFixedThreadPool.(ForkJoinPool是一個可以執(zhí)行ForkJoinTask的ExcuteService漏峰,它采用了work-stealing模式:所有在池中的線程嘗試去執(zhí)行其他線程創(chuàng)建的任務糠悼,這樣很更加高效);
delay
delay()方法相當于Thread.sleep()的功能浅乔,但是比它更好:它不會阻塞線程倔喂,而只是掛起協(xié)程本身.當協(xié)程在等待時,線程將返回到池中, 當?shù)却瓿蓵r, 協(xié)同將在池中的空閑線程上恢復.
說到delay()這個方法就不能不提一下suspend關(guān)鍵字,在源碼中可以看見delay()這個方法前面有個suspend關(guān)鍵字修飾,我們稱之為掛起方法.掛起方法只能從協(xié)程代碼內(nèi)部調(diào)用靖苇,普通的非協(xié)程的代碼不能調(diào)用.掛起方法只允許由協(xié)程或者另外一個掛起方法里面調(diào)用.
????????????????????????????????????????????????????????????????????????????????????????????????????????????????????-----------------------------------------------------------------------------未完待續(xù)