創建類的實例
要創建一個類的實例,我們就像普通函數一樣調用構造函數:
val invoice = Invoice() val customer = Customer("Joe Smith")
注意 Kotlin 並沒有 new 關鍵字。
繼承
在 Kotlin 中所有類都有一個共同的超類 Any
,這對於沒有超類型聲明的類是默認超類
class Example // 從 Any 隱式繼承
Any
不是 java.lang.Object
;尤其是,它除了 equals()
、hashCode()
和toString()
外沒有任何成員。
要聲明一個顯式的超類型,我們把類型放到類頭的冒號之后:
open class Base(p: Int) class Derived(p: Int) : Base(p)
類上的 open 標注與 Java 中 final 相反,它允許其他類 從這個類繼承。默認情況下,在 Kotlin 中所有的類都是 final, 對應於 Effective Java書中的 第 17 條:要么為繼承而設計,並提供文檔說明,要么就禁止繼承。
覆蓋方法
我們之前提到過,Kotlin 力求清晰顯式。與 Java 不同,Kotlin 需要顯式 標注可覆蓋的成員(我們稱之為開放)和覆蓋后的成員:
open class Base { open fun v() {} fun nv() {} } class Derived() : Base() { override fun v() {} }
標記為 override 的成員本身是開放的,也就是說,它可以在子類中覆蓋。如果你想禁止再次覆蓋,使用 final 關鍵字:
open class AnotherDerived() : Base() { final override fun v() {} }
覆蓋屬性
屬性覆蓋與方法覆蓋類似;在超類中聲明然后在派生類中重新聲明的屬性必須以 override 開頭,並且它們必須具有兼容的類型。每個聲明的屬性可以由具有初始化器的屬性或者具有 getter 方法的屬性覆蓋。
open class Foo { open val x: Int get { …… } } class Bar1 : Foo() { override val x: Int = …… }
你也可以用一個 var
屬性覆蓋一個 val
屬性,但反之則不行。這是允許的,因為一個 val
屬性本質上聲明了一個 getter 方法,而將其覆蓋為 var
只是在子類中額外聲明一個 setter 方法。
伴生對象
與 Java 或 C# 不同,在 Kotlin 中類沒有靜態方法。在大多數情況下,它建議簡單地使用 包級函數。