【Kotlin】接口 ( 声明 | 实现 | 接口方法 | 接口属性 | 接口覆盖冲突 | 接口继承 )
文章目錄
- I . 接口總結
- II . 接口聲明
- III . 接口實現
- IV . 接口中的方法
- V . 接口中的屬性 ( 變量 / 常量 )
- VI . 接口中的屬性屬性覆蓋 ( 變量 / 常量 )
- VII . 接口覆蓋沖突問題
- VIII . 接口繼承接口
I . 接口總結
接口總結 :
① 聲明與實現 : 使用 interface 關鍵字聲明接口 , 實現時需要重寫所有的抽象成員 ( 屬性 / 方法 ) ;
② 接口成員 : 接口中的 正常成員屬性和成員方法默認使用 open 關鍵字修飾 , 接口中的抽象成員屬性和抽象成員方法默認使用 abstract open 關鍵字修飾 ;
③ 接口屬性及覆蓋 : 變量屬性聲明成抽象屬性 , 常量屬性可以聲明成抽象屬性 , 也可以添加訪問器 ;
④ 接口覆蓋沖突問題 : 實現類實現多個接口 , 使用 super<接口名稱> 調用不同接口的正常方法 ;
II . 接口聲明
1 . 接口聲明 : 接口使用 interface 接口名稱 格式定義 ;
① 接口默認 open 修飾 : 接口 , 默認使用 open 關鍵字修飾 , 可以直接繼承 ;
② 接口方法默認 open 修飾 : 接口中的方法 , 默認使用 open 關鍵字修飾 , 可以直接 override 重寫 ; 抽象方法可以省略 abstract 關鍵字修飾 ;
② 接口屬性默認 open 修飾 : 接口中的屬性 , 默認使用 open 關鍵字修飾 , 可以直接 override 重寫 ; 抽象屬性可以省略 abstract 關鍵字修飾 ;
//定義接口 interface Intf{}III . 接口實現
接口實現 :
① 沒有構造函數委托 : 實現接口時不用調用其構造函數 , 因此在子類聲明時 , 接口名稱后沒有括號 ;
② 必須重寫抽象方法與抽象屬性 : 接口中的沒有初始化的屬性是抽象屬性 , 沒有方法體的方法是抽象方法 , 其省略了 abstract 和 open 關鍵字 ;
//接口定義 interface Intf{//抽象屬性var age : Int//抽象方法fun action_abstract()}//接口實現 , 注意沒有構造函數委托 class Impl : Intf {//重寫抽象屬性override var age: Int = 18//重寫抽象方法override fun action_abstract() {println("Impl : action_abstract")} }IV . 接口中的方法
1 . 接口中的方法 : 接口中的方法默認使用 open 修飾 , 可以直接在實現類中重寫覆蓋 ;
① 抽象方法 : 接口中可以定義抽象方法 , 接口中沒有方法體的抽象方法可以省略 abstract 關鍵字 , 所有方法默認使用 open 修飾 ;
② 正常方法 : 也可以定義普通的方法 , 普通方法默認使用 open 修飾 ;
③ 與 Java 對比 : 這一點與 Java 不同 , Java 中接口必須都是抽象方法 ;
interface Intf{//接口中的方法默認使用 abstract 修飾fun action_abstract()//接口中可以定義正常方法fun action_real(){println("action_real")} }2 . 接口中方法重寫 : 重寫的方法必須使用 override 關鍵字修飾 ;
//接口定義 interface Intf{//接口中的方法默認使用 abstract open 修飾fun action_abstract()//接口中可以定義正常方法 , 默認使用 open 修飾fun action_real(){println("Intf : action_real")} }//接口實現類 abstract class Impl : Intf {//實現類中實現接口的抽象方法override fun action_abstract() {println("Impl : action_abstract")}//實現類中重寫接口中的正常方法override fun action_real() {super.action_real()println("Impl : action_real")} }V . 接口中的屬性 ( 變量 / 常量 )
1 . 接口屬性 : 接口無法實例化 , 無法保存狀態 , 接口中的屬性不能初始化 , 此時有兩種選擇 : ① 將該屬性定義成抽象的 ( 變量常量都可 ) , ② 提供 get 方法 ( 只有常量才可以 ) ;
① 抽象屬性 ( 變量 / 常量 ) : 被 abstract 修飾的 常量 var 或 變量 val 屬性 , 沒有初始化值 , 沒有 getter 和 setter 方法 ;
interface Intf{//抽象屬性 常量 , 默認被 abstract open 修飾 ( 可省略 )abstract open val age : Int//抽象屬性 變量 , 默認被 abstract open 修飾 ( 可省略 )abstract open var name : String }② 省略的修飾符 ( 變量 / 常量 ) : 接口中的屬性和方法默認自帶 open 修飾符 , 接口中的抽象屬性 和 抽象方法 可以省略 abstract , 因此這里可以省略 open 和 abstract 關鍵字 , 加上也不會出錯 ;
( 下面的抽象屬性與 ① 中的抽象屬性是等價的 )
interface Intf{//抽象屬性 常量 , 默認被 abstract open 修飾 ( 可省略 )val age : Int//抽象屬性 變量 , 默認被 abstract open 修飾 ( 可省略 )var name : String }③ 提供訪問器 ( 常量 ) : 可以給屬性提供一個訪問器 , 但是明顯接口無法實例化 , 該訪問器調用不了 ;
( 常量可以提供一個訪問器 , 變量只能定義成抽象屬性 )
interface Intf{//抽象屬性 常量 , 常量可以提供一個訪問器val age : Intget() = 18//抽象屬性 變量 , 變量只能聲明成抽象屬性 , 不能添加訪問器var name : String }VI . 接口中的屬性屬性覆蓋 ( 變量 / 常量 )
接口中的屬性覆蓋 :
① 抽象屬性 : 接口中的 變量 / 常量 屬性可以聲明成抽象的 ;
② 關于訪問器 : 只有常量才能使用添加訪問器替代抽象屬性方案 , 變量不能添加訪問器 ;
③ 常量與變量 : 覆蓋屬性 , 可以使用變量覆蓋常量 , 反過來不行 , 變量只能使用變量覆蓋 ;
//1 . 接口定義 interface Intf{//抽象屬性 常量 , 默認被 abstract open 修飾 ( 可省略 )//常量可以提供一個訪問器 , 變量只能聲明成抽象屬性 , 不能添加訪問器val age : Int//抽象屬性 變量 , 默認被 abstract open 修飾 ( 可省略 )//常量可以提供一個訪問器 , 變量只能聲明成抽象屬性 , 不能添加訪問器var name : String }//2 . 接口實現類 abstract class Impl : Intf {//覆蓋屬性 , 可以使用變量覆蓋常量 , 反過來不行override var age: Int = 18//覆蓋屬性 , 變量只能使用變量覆蓋override var name: String = "Tom" }VII . 接口覆蓋沖突問題
1 . 接口覆蓋沖突問題描述 : 一個類可以實現多個接口 , 如果多個接口中出現相同函數簽名的函數 ( 正常帶方法體的函數 ) , 如何調用不同接口的相同簽名函數 ; ( 注意 : 這里調用的方法是有方法體的正常方法 )
2 . 覆蓋沖突解決方案 : 可以通過 super<接口名> 調用不同接口的正常方法 ;
3 . 代碼示例 : Intf1 和 Intf2 接口中都定義了非抽象函數 action_real , Impl 類實現了兩個接口 , 通過使用 super.action_real() 調用 Intf1 中的 action_real 方法 , 通過使用 super.action_real() 調用 Intf2 中的 action_real 方法
//接口 1 定義 interface Intf1{fun action_abstract()fun action_real(){println("Intf1 : action_real")} }//接口 2 定義 interface Intf2{fun action_abstract()fun action_real(){println("Intf2 : action_real")} }//實現兩個接口 class Impl : Intf1 , Intf2 {override fun action_abstract() {println("Impl : action_abstract")}override fun action_real() {//調用 Intf1 接口中的 action_real 方法super<Intf1>.action_real()//調用 Intf2 接口中的 action_real 方法super<Intf2>.action_real()} }VIII . 接口繼承接口
接口繼承接口 :
① 派生接口繼承 : 一個接口可以繼承另一個接口 , 派生接口擁有基類接口的成員 ;
② 派生接口新成員 : 派生接口聲明新的接口成員和屬性 ;
③ 子類實現派生接口 : 需要實現兩個接口的所有的抽象成員 ( 屬性 / 方法 ) ;
//接口定義 interface Intf1{//抽象屬性var age : Int//抽象方法fun action_abstract() }//接口定義 interface Intf2 : Intf1{//抽象屬性var name : String//抽象方法fun action_abstract2() }//接口實現 , 注意沒有構造函數委托 //需要實現 Intf1 和 Intf2 中的抽象成員 class Impl : Intf2 {override var name: String = "Tom"override var age: Int = 18override fun action_abstract() {println("Impl : action_abstract")}override fun action_abstract2() {println("Impl : action_abstract")} }總結
以上是生活随笔為你收集整理的【Kotlin】接口 ( 声明 | 实现 | 接口方法 | 接口属性 | 接口覆盖冲突 | 接口继承 )的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Kotlin】抽象类 ( 声明 | 抽
- 下一篇: 【Kotlin】属性 与 幕后字段 (