Kotlin之類繼承結構
介面
使用interface
關鍵字來宣告一個介面
interface Clickable{
fun click()
}
接下來實現這個介面
class Button : Clickable{
override fun click() = println("I was clicked")
}
Kotlin中使用冒號代替了Java中的extends
和implements
關鍵字。和Java一樣,一個類可以實現多個任意介面,但只能繼承一個類
與Java中的@Override
註解類似,override
修飾符用來標註被重寫的父類的介面的方法和屬性。
介面可以有一個預設的實現,當然也可以在子類中重新定義showOff
函式的實現
interface Clickable{
fun click()
fun showOff() = println("I'm clickable!") //帶預設實現的方法
}
定義另一個實現了同樣方法的介面
interface Focusable{
fun setFocus(b:Boolean) = println("I ${if (b) "got" else "lose"} focus")
fun showOff() = println("I'm focusable!")
}
然後在一個子類中同時實現這兩個介面,它們每一個都包含了帶預設實現的showOff
方法,那麼子類中你必須要實現這個方法,在Java中可以把基類的名字放在super
關鍵字的前面;但是在Kotlin中需要把基類的名字放在尖括號中
class Button2 : Clickable,Focusable{
override fun showOff() {
super<Clickable>.showOff()
super<Focusable>.showOff()
}
override fun click() {}
}
注意:在Java中實現Kotlin的介面,Java並不支援介面中的預設方法,子類必須實現方法體
open、final和abstract修飾符:預設為final
宣告一個帶open
的open
類
open class RichButton : Clickable{ //這個類是open的:其他類可以繼承它
override fun click() {}//這個函式重寫了一個open函式並且它本身同樣是open的
fun disable(){} //這個函式是final的:不能在子類中重寫它
open fun animate(){}//這個函式是open的:可以在子類中重寫它
}
注意:如果你重寫了一個基類或者介面的成員,重寫了的成員同樣預設是open
的。如果你想阻止你類的子類重寫你的實現,可以顯示地將重寫的成員標註為final
open class RichButton: Clickable {
final override fun click(){}
}
抽象類
在Kotlin中,與Java一樣,可以將一個類宣告成abstract
的,這種類不能被例項化。並且它內部的抽象成員始終是open
的,因此不需要顯示地使用open
修飾符
abstract class Animated{
abstract fun animate()
open fun stopAnimating(){}
fun animateTwice(){}
}
修飾符
- 訪問修飾符
普通類中成員預設為final
;介面、抽象類中成員預設為open
;若子類繼承的父類方法為open
,那麼子類重寫後的方法也為open
修飾符 | 相關成員 | 評註 |
---|---|---|
final | 不能被重寫 | 類中成員預設使用 |
open | 可以被重寫 | 需要明確的表明 |
abstract | 必須被重寫 | 只能在抽象類中使用;抽象成員不能有實現 |
override | 重寫父類或介面中的成員 | 如果沒有使用final表明,重寫的成員預設是開放的 |
- 可見性修飾符(預設為
public
)
修飾符 | 類成員 | 頂層宣告 |
---|---|---|
public(預設) | 所有地方可見 | 所有地方可見 |
internal | 模組中可見 | 模組中可見 |
protected | 子類中可見 | ------------ |
private | 類中可見 | 檔案中可見 |
內部類和巢狀類
Kotlin沒有顯示的巢狀類與Java中的static
巢狀類一樣,要把它變成內部類來持有一個外部類的引用要用inner
,下面是Java和Kotlin在這個行為上的不同:
類A在另一個類B中宣告 | 在Java中 | 在Kotlin中 |
---|---|---|
巢狀類(不儲存外部類的引用) | static class A | class A |
內部類(儲存外部類的引用) | class A | inner class A |
密封類:定義受限的類繼承結構
在使用when
表示式時,Kotlin編譯期會強制檢查預設選項。所以不得不新增一個預設的分支。Kotlin為這個問題提供了一個解決方案:sealed
類。為父類新增一個sealed
修飾符,對可能建立的子類做出嚴格的限制,所有的直接子類都必須巢狀在父類中
sealed class Expr //將基類標記成密封的,sealed修飾符隱含的是open的
{
class Num(val value:Int) : Expr() //將所有可能的類作為巢狀類
class Sum(val left:Expr,val right:Expr) : Expr()
}
fun simplifyEval2(e:Expr):Int =
when(e){// “when”表示式涵蓋了所有可能的情況,所以不再需要“else”分支
is Expr.Num ->
e.value
is Expr.Sum ->
simplifyEval2(e.left) + simplifyEval2(e.right)
}
相關文章
- Kotlin——中級篇(四):繼承類詳解Kotlin繼承
- 類的繼承_子類繼承父類繼承
- Kotlin學習快速入門(3)——類 繼承 介面Kotlin繼承
- Java之繼承和抽象類Java繼承抽象
- 類的繼承繼承
- Javascript繼承2:建立即繼承—-建構函式繼承JavaScript繼承函式
- PLC結構化文字(ST)——繼承(inheritance)繼承
- 原型繼承:子類原型繼承
- Python類的繼承Python繼承
- C++ | 類繼承C++繼承
- 20200109 - 類的繼承繼承
- TypeScript 介面繼承類TypeScript繼承
- Python學習手冊之類和繼承Python繼承
- 繼承 基類與派生類繼承
- javascript之繼承JavaScript繼承
- js之繼承JS繼承
- python之繼承Python繼承
- python多執行緒之從Thread類繼承Python執行緒thread繼承
- 【Python】python類的繼承Python繼承
- 類的繼承和派生繼承
- 類的繼承圖解繼承圖解
- es5繼承和es6類和繼承繼承
- python 基礎之繼承、重寫、多繼承Python繼承
- js 繼承小結JS繼承
- JavaScript繼承總結JavaScript繼承
- odoo 繼承(owl繼承、web繼承、view繼承)Odoo繼承WebView
- 區分:派生類指定基類建構函式、繼承構造、委託構造函式繼承
- Kotlin 物件導向程式設計 (OOP) 基礎:類、物件與繼承詳解Kotlin物件程式設計OOP繼承
- JavaScript(2)之——繼承JavaScript繼承
- JavaScript之物件繼承JavaScript物件繼承
- PHP 抽象類繼承抽象類時的注意點PHP 抽象類繼承抽象類時的注意點PHP抽象繼承
- JS 總結之原型繼承的幾種方式JS原型繼承
- 物件導向 -- 三大特性之繼承 補充 抽象類 介面類物件繼承抽象
- ES6 - 類與繼承繼承
- 菱形繼承與虛基類繼承
- 物件、原型鏈、類、繼承【上】物件原型繼承
- JavaSE-繼承(包含Object類)Java繼承Object
- JavaScript基礎: 類與繼承JavaScript繼承