(二)Kotlin 面向物件
阿新 • • 發佈:2018-12-14
文章目錄
- 一、面向物件的概念
- 二、抽象類與介面
- 三、類的繼承與介面的實現
- 四、類及其成員的可見性
- 五、object
- 六、伴生物件與靜態成員
- 七、方法過載(Overloads)和預設引數
- 八、擴充套件成員(二次加工)
- 九、屬性代理
- 十、資料類(data class)
- 十一、內部類
- 十二、列舉類
- 十二、密封類(sealed class)
- 上一篇:[(一)Kotlin 面向物件](https://blog.csdn.net/qq_20538515/article/details/84987744)
- 下一篇:[(三)Kotlin 高階函式](https://blog.csdn.net/qq_20538515/article/details/84988237)
一、面向物件的概念
- 本質上就是解決如何用程式描述世界的問題
- 討論如何把實際存在的東西對映成程式的類和物件
- 一種程式設計的思路、思想、方法
- 程式設計層面的概念
- 設計模式:前人的程式設計經驗
二、抽象類與介面
相當於半成品與協議
1、介面
- 介面,直觀理解就是一種約定
interface InputDevice{
fun input(event: Any)
}
- 介面不能有狀態
- 必須由類對其進行實現後使用
2、抽象類
- 實現了一部分協議的半成品
- 可以有狀態,可以有方法實現
- 必須由子類繼承後使用
3、抽象類和介面的共性
- 比較抽象,不能直接例項化
- 需要有子類(實現類)實現的方法
- 父類(介面)變數可以接受子類(實現類)的賦值
3、抽象類和介面的區別
- 抽象類有狀態,介面沒有狀態
- 抽象類有方法實現,介面只能有無狀態的預設實現
- 抽象類只能單繼承,介面可以多實現
- 抽象類反應本質,介面體現能力
三、類的繼承與介面的實現
- 父類需要 open 才可以被繼承
- 父類方法、屬性需要 open 才可以倍複寫
- 介面、介面方法、抽象類預設為 open
- 複寫父類(介面)成員需要 override 關鍵字
- class D:A(),B,C
- 注意繼承類時實際上呼叫了父類構造方法
- 類只能單繼承,介面可以多實現
介面代理
- class Manager(driver: Driver):Driver by driver
- 介面方法實現交給代理類實現
介面方法衝突
- 介面方法可以有預設實現
- 簽名一致且返回值相同的衝突
- 子類(實現類)必須複寫衝突方法
- super<[父類(介面)名]>.[方法名]([引數列表])
四、類及其成員的可見性
Kotlin | Java |
---|---|
private | private |
protected | protected |
– | default(包內可見) |
internal(模組內可見) | – |
public | public |
五、object
- 只有一個例項的類(單例)
- 不能自定義構造方法
- 可以實現介面、繼承父類
- 本質上就是單例模式最基本的實現
六、伴生物件與靜態成員
- 每個類可以對應一個伴生物件
- 伴生物件的成員全域性獨一份
- 伴生物件的成員類似Java的靜態成員
- 靜態成員考慮用包級函式、變數代替
- 使用JvmField和JvmStatic,可以讓伴生物件在Java中使用時看起來像靜態成員和靜態方法
七、方法過載(Overloads)和預設引數
過載
- 寫了一個方法和已經存在的方法重名,引數不相同
- Jvm函式簽名的概念:函式名、引數列表
- 跟返回值沒有關係
預設引數
- 為函式引數設定一個預設值
- 可以為任意位置的引數設定預設值
- 函式呼叫產生混淆時用具名引數
方法過載與預設引數
- 方法過載與預設引數可以互相轉換,在Java中呼叫有預設引數的方法時,該方法需要使用註解@JvmOverloads
- 避免定義關係不大的過載方法
八、擴充套件成員(二次加工)
- 為現有類新增方法、屬性
fun X.y():Z{...}
val X.m
//注意擴充套件屬性不能初始化,類似介面屬性
- Java 呼叫擴充套件成員類似呼叫靜態方法
九、屬性代理
- 定義方法
val/var <property name>: <Type> by <expression>
- 代理者需要實現相應的setValue/getValue方法
- by lazy 就是在第一次使用的時候才去例項化物件
十、資料類(data class)
- 預設實現 copy()、toString()、equals()等方法
- 編譯器預設生成component[1-N]方法,可以自己複寫
data class China(val code:Int,name: String)
val (a,b) = China(0,"中國")
pringln("$a -> $b")
- allOpen和noArg 外掛解決data class 的類被解析成final類,並且無空構造方法的問題
//build.gradle 中的 dependencies 中新增
dependencies{
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "org.jetbrains.kotlin:kotlin-noarg:$kotlin_version"
classpath "org.jetbrains.kotlin:kotlin-allopen:$kotlin_version"
}
//build.gradle 中 新增外掛的應用
apply plugin: 'kotlin-noarg'
apply plugin: 'kotlin-allopen'
// 外掛的配置
noArg{
annotation("註解類名")
}
allOpen{
annotation("註解類名")
}
- 屬性需要寫到構造方法,初始化時需要傳入引數
十一、內部類
- 定義在類內部的類
- 與類成員有相似的訪問控制
- 預設是靜態內部類,非靜態用 inner 關鍵字
- [email protected] 與 [email protected]
匿名內部類
- 沒有定義名字的類
- 類名編譯時生成,類似Outter$1.class
- 可繼承父類、實現多個介面,與Java 不一樣
十二、列舉類
- 例項可數的類,注意列舉也是類
- 可以修改構造方法,新增成員
- 可以提升程式碼的表現力,也有一定的效能開銷
十二、密封類(sealed class)
- 子類可數的類
- <V1.1,子類必須定義為密封類的內部類
- v1.1開始,子類只需要與密封類在同一個檔案中
- 子類可以有多個構造引數
- 表示狀態適合使用列舉,需要傳輸指令時適合使用密封類