第七篇:Kotlin之面向對象升級(一)

上篇:Kotlin之面向對象簡單

本章節(jié)來介紹Kotlin面向對象的高級部分:

一. 擴展:kotlin的擴展是一個很獨特的功能醒叁,java本身支持擴展亮曹,Kotlin為了讓擴展能在JVM平臺上運行,必須做了一些獨特的處理淤毛。

1.擴展方法:

擴展方法的語法很簡單,其實就是定義一個函數,只是函數名不要寫成簡單的函數采呐,而是要在函數名前添加被擴展的類(或接口)名和點號(.)。例如:

如上:程序為Raw類擴展了info()方法之后搁骑,就像為Raw類增加了info()方法一樣斧吐,所有的Raw對象都可調用info()方法又固。不僅如此,Raw類的子類的實例也可調用info方法煤率。

當然仰冠,擴展也可以為Kotlin系統提供類的增加方法。例如:

切記:用為指定了Int的泛型蝶糯,所以只能對該泛型為Int的list集合可以調用洋只。如果想對所有類型的泛型可以調用的話,可以不指定明確的類型裳涛。(具體泛型的使用會在接下來的泛型篇章里細講)

實際上木张,Kotlin的擴展并沒有真正地修改所有的擴展的類,被擴展的類還是原來的類端三,沒有任何改變舷礼。Kotlin擴展的本質就是定義了一個函數,當程序用對象調用擴展方法時郊闯,Kotlin在編譯時會執(zhí)行靜態(tài)解析--就是根據調用對象妻献,方法名找到擴展函數,轉換為函數調用团赁。

介紹一下子類和父類同時有一個擴展名一樣擴展育拨,調用的時候是如何執(zhí)行的,如下:

如果getName是重寫的方法欢摄,執(zhí)行返回的一定是son熬丧,但是因為擴展執(zhí)行的是靜態(tài)解析(有編譯時候的類型決定,編譯的類型是Base),所以調用的是Base類的getName方法怀挠,返回的是base析蝴。?

此外還有一點需要注意的是,成員的方法的優(yōu)先級高于擴展的方法绿淋,所有如果成員方法和擴展方法具有同一個名字的時候闷畸,那么系統總是會執(zhí)行成員方法,而不會執(zhí)行擴展方法吞滞。(當然參數不同的話佑菩,就無所謂了)

也可以為可空類型擴展方法:如下:

Any這個關鍵字我忘記了在前面介紹沒有,所在還是提上一句裁赠。 Any就是java的object殿漠,在kotlin是一切類型的父類。

2.擴展屬性

Kotlin也允許擴展屬性佩捞,但由于Kotlin的擴展并不是真正修改目標類凸舵,因此Koltin擴展的屬性其實是通過get和set方法實現的,沒有幕后字段失尖。簡單的來說啊奄,擴展的屬性只能是計算屬性!

kotlin的擴展屬性的如下要求:

1.擴展的屬性不能有初始化值(因為沒有存儲屬性值的幕后字段)

2.不能用field關鍵字顯示幕后字段

3.擴展只讀屬性必須提供getter方法掀潮,擴展讀寫屬性必須提供getter和setter方法菇夸。

匿名擴展函數:與原來的區(qū)別在于. + 方法名,將方法名移動到前面:如下:

對于擴展在舉一個最后的例子仪吧。如下:

3.const 宏的介紹

Kotlin與java的一個重大區(qū)別是:Kotlin的final修飾符不能修飾局部變量庄新,因此open自然也不能修飾局部變量。所以Kotlin提供了宏的概念薯鼠,Kotlin提供了const用來修飾可執(zhí)行“宏替換”的常量择诈。定于如下:

const的使用規(guī)則如下:

1.位于頂層或者是對象表達式的成員

2.初始化為基本類型值或者字符串類型

3.沒有自定義的getter方法。

定義宏變量的時候需要注意的是:

MAX_VALUE_ONE這樣的寫法可以出皇,能夠得到確切的值羞芍,但是MAX_VALUE_TWO這樣的寫法是錯誤的,在編譯的時候無法得到確切的值郊艘。

4.final和open

kotlin 有一個非常特別的設計:它會為非抽象類自動添加final修飾符荷科,也會為非抽象方法,非抽象屬性等無須重寫的成員自動添加final修飾符纱注。如果開發(fā)者希望取消kotlin自動添加final修飾符畏浆,可以使用open修飾符,open修飾符與final是反義詞狞贱。(對于這樣的設計刻获,我個人是比較青睞的。因為一個類加上final和不加上final對于性能來說其實差距還是蠻大的瞎嬉,不知道原因的同學可以查閱一下蝎毡。但是對于好多開發(fā)者來說,不會注意這個類加不加final佑颇,即使這個類不需要繼承顶掉。所以說kotlin其實對java和java開發(fā)者來說,真的就是一種優(yōu)化代碼而已挑胸,方便開發(fā)高性能的代碼)痒筒。

二.類的種類:

1.不可變類:不可變類的意思是創(chuàng)建該類的實例后,該實例的屬性值是不可以改變的茬贵。其實很簡單簿透,就是對于參數加上val修飾。如下:

與可變類相比解藻,不可變類的實例在整個生命周期中永遠處于初始化狀態(tài)老充,他的屬性值不可以改變。

下面有這樣一個例子:



通過這樣仍然可以對address里邊的屬性進行改變螟左,在語義上這樣是不對的啡浊,那么如何實現徹徹底底的不可變類呢觅够。如下:

這樣寫就能徹徹底底實現不可變類啦~

密封類:密封類是一種特殊的抽象類,專門用于派生子類巷嚣。密封類與普通類的區(qū)別在于:密封類的子類是固定喘先。密封類的子類必須與密封類本身在同一個文件中,在其他文件中則不能為密封類派生子類廷粒,這樣就限制了在其他文件中派生子類窘拯。

上邊定義了一個密封類,接下來即可在該密封類中定義抽象方法坝茎,由此可見涤姊,密封類的本質就是抽象類。有規(guī)則可以知道嗤放,密封類的所有構造器都必須是private的思喊,不管開發(fā)者是否使用private修飾,系統都會為之自動添加private修飾斤吐。

有人會問到:那些密封類的好處是什么呢搔涝?因為密封類的子類是固定的,編譯器可以清楚地知道密封類有多少個子類和措,所以在使用when表達式的時候庄呈,編譯器可以知道是否覆蓋了所有情況,從而判斷是否需要添加else子句派阱。

嵌套類和內部類:

Kotlin的嵌套類相當于java的靜態(tài)內部類诬留。而kotlin的內部類相當于java的非靜態(tài)內部類。(在kotlin使用內部類的時候贫母,用到了inner這個修飾符 ? inner class className {})

匿名內部類:

Java有一個非常實用的功能:匿名內部類文兑,Kotlin則徹底拋棄了這個功能。不過同學不必擔心腺劣,Kotlin提供了一個更加強大的語法:對象表達式绿贞。

對象表達式和對象聲明:

對象表達式還有如下規(guī)則:

1.對象表達式不能是抽象類,因為系統在創(chuàng)建對象表達式時會立即創(chuàng)建對象橘原。因此不允許將對象表達式定義抽象類籍铁。

2.對象表達式不能定義構造器。但對象表達式可以定義初始化塊趾断,可以通過初始化塊來完成構造器需要完成的事情拒名。

3.對象表達式可以包含內部類(有inner修飾的內部類),不能包含嵌套類芋酌。

指定零個父類型的對象表達式:

當然也可以指定多個父類型的對象表達式:

對象表達式用來代替java的匿名內部類的增显。那么對象聲明就可以實現單例啦~什么是對象聲明呢?如下:

這個就是對象聲明脐帝,和對象表達式很相近同云。他們之前的不同在于對象聲明不能定義在函數或者方法里邊糖权。

伴生對象:

在談到對象聲明的時候,還不得不說另外一個概念就是伴生對象:在類中定義的對象聲明梢杭,可以用companion修飾温兼,這樣該對象就變成了伴生對象。每個類最多只能定義一個伴生對象武契,伴生對象相當于外部類的對象,程序可通過外部類直接訪問:那么我們就來實現kotlin的單例吧~如下:


by修飾符這個是kotlin的委托荡含,我會在接下來篇章里詳細介紹咒唆。companion object {} 就完完整整的實現了單例。因為kotlin不在用static修飾符了释液。全释。那么可以用伴生對象來定義靜態(tài)的常量。

如果細讀的同學可以會問:你剛剛說的是伴生的修飾符 + 對象聲明來實現的那么應該怎么寫吧误债,怎么少了名字呢浸船?

其實名字完全可以省略的,因為在調用的過程中寝蹈,是當前的類名.instance李命, 調用變量的話是類名.DB_NAME等等,所以起不起名字都沒有關系箫老。

伴生對象擴展:

這樣就可以實現對伴生對象擴展啦~~

三.接口:

接口定義的方法既可是抽象方法封字,也可是非抽象的方法。如果一個只讀的屬性沒有定義getter方法耍鬓,kotlin會自動為該屬性添加abstract修飾符阔籽,如果一個讀寫屬性沒有定義getter和setter方法,kotlin會自動為該屬性添加abstract修飾符牲蜀。

Kotlin接口和java接口還有一個區(qū)別就是:Java接口中的所有成員都會自動使用public修飾符笆制。如果要添加訪問修飾符,則只能用public涣达;如果不加修飾符在辆,則系統默認是public。對于不需要被實現重寫的成員呢峭判,我們可以定義private或public修飾(在kotlin接口里开缎,成員可以不必須是抽象的。方法可以定義實體)林螃。默認的情況下是public修飾符代替奕删。

因為本篇幅有點過長,還剩下枚舉和類的委托沒有介紹疗认,打算在下一篇介紹完残。下篇近期會更新伏钠。如果感覺還不錯的同學那么點波關注吧~~

?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市谨设,隨后出現的幾起案子熟掂,更是在濱河造成了極大的恐慌,老刑警劉巖扎拣,帶你破解...
    沈念sama閱讀 218,640評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件赴肚,死亡現場離奇詭異,居然都是意外死亡二蓝,警方通過查閱死者的電腦和手機誉券,發(fā)現死者居然都...
    沈念sama閱讀 93,254評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來刊愚,“玉大人踊跟,你說我怎么就攤上這事∨阜蹋” “怎么了商玫?”我有些...
    開封第一講書人閱讀 165,011評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長牡借。 經常有香客問我拳昌,道長,這世上最難降的妖魔是什么蓖捶? 我笑而不...
    開封第一講書人閱讀 58,755評論 1 294
  • 正文 為了忘掉前任牵敷,我火速辦了婚禮揩徊,結果婚禮上酬荞,老公的妹妹穿的比我還像新娘锹安。我一直安慰自己,他們只是感情好并闲,可當我...
    茶點故事閱讀 67,774評論 6 392
  • 文/花漫 我一把揭開白布细睡。 她就那樣靜靜地躺著,像睡著了一般帝火。 火紅的嫁衣襯著肌膚如雪溜徙。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,610評論 1 305
  • 那天犀填,我揣著相機與錄音蠢壹,去河邊找鬼。 笑死九巡,一個胖子當著我的面吹牛图贸,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,352評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼疏日,長吁一口氣:“原來是場噩夢啊……” “哼偿洁!你這毒婦竟也來了?” 一聲冷哼從身側響起沟优,我...
    開封第一講書人閱讀 39,257評論 0 276
  • 序言:老撾萬榮一對情侶失蹤涕滋,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后挠阁,有當地人在樹林里發(fā)現了一具尸體宾肺,經...
    沈念sama閱讀 45,717評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,894評論 3 336
  • 正文 我和宋清朗相戀三年侵俗,在試婚紗的時候發(fā)現自己被綠了爱榕。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,021評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡坡慌,死狀恐怖,靈堂內的尸體忽然破棺而出藻三,到底是詐尸還是另有隱情洪橘,我是刑警寧澤,帶...
    沈念sama閱讀 35,735評論 5 346
  • 正文 年R本政府宣布棵帽,位于F島的核電站熄求,受9級特大地震影響,放射性物質發(fā)生泄漏逗概。R本人自食惡果不足惜弟晚,卻給世界環(huán)境...
    茶點故事閱讀 41,354評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望逾苫。 院中可真熱鬧卿城,春花似錦、人聲如沸铅搓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,936評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽星掰。三九已至多望,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間氢烘,已是汗流浹背怀偷。 一陣腳步聲響...
    開封第一講書人閱讀 33,054評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留播玖,地道東北人椎工。 一個月前我還...
    沈念sama閱讀 48,224評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親晋渺。 傳聞我的和親對象是個殘疾皇子镰绎,可洞房花燭夜當晚...
    茶點故事閱讀 44,974評論 2 355

推薦閱讀更多精彩內容