類
類的定義
modifiers ("class" | "interface") SimpleName
typeParameters?
primaryConstructor?
(":" annotations delegationSpecifier{","})?
typeConstraints
(classBody? | enumClassBody)
classModifier: 類屬性修飾符,標(biāo)示類本身特性背稼。
abstract //抽象類標(biāo)示
final //標(biāo)示類不可繼承贰军,默認(rèn)屬性
enum //標(biāo)示類為枚舉
open //類可繼承,類默認(rèn)是final的
annotation //注解類
accessModifier: 訪問權(quán)限修飾符
private //僅在同一個文件中可見
protected //同一個文件中或子類可見
public //所有調(diào)用的地方都可見
internal //同一個模塊中可見
1 當(dāng)Kotlin中的類需要構(gòu)造函數(shù)時蟹肘,可以有一個主構(gòu)造函數(shù)和多個次構(gòu)造函數(shù)词疼,可以沒有次構(gòu)造函數(shù)。主構(gòu)造函數(shù)在類名后帘腹。
2 默認(rèn)任何類都是基礎(chǔ)繼承自 Any (與java中的 Object 類似)贰盗,但是我們可以繼承其它類。
3 所有的類默認(rèn)都是不可繼承的(final)阳欲,所以我們只能繼承那些明確聲明 open 或者 abstract 的類:
4 抽象類---Kotlin中的抽象類允許有abstract修飾的成員方法舵盈,非抽象類不允許有抽象方法;
5 抽象類默認(rèn)是可被繼承的球化,接口是特殊的抽象類秽晚,允許有抽象方法:
open class Animal(name: String)
class Person(name: String, surname: String) : Animal(name)
函數(shù)
構(gòu)造函數(shù)
主構(gòu)造函數(shù)
1 主構(gòu)造函數(shù)不能包含任何的代碼。初始化的代碼可以放到以 init 關(guān)鍵字作為前綴的初始化塊中筒愚;
class Person(name: String){
init{
//初始化塊
}
}
2 可以直接把primary constructor中的參數(shù)直接聲明成為類的屬性赴蝇, 函數(shù)的參數(shù)聲明可以是val也可以是var,當(dāng)在主函數(shù)中聲明后可以當(dāng)做全局變量使用
class Person(var name: String)//name全局變量使用
3巢掺、當(dāng)屬性不在主構(gòu)造函數(shù)中聲明又想當(dāng)全局變量使用句伶,可在類中聲明芍耘,主函數(shù)中聲明是簡化了其寫法。
4 當(dāng)屬性不在主函數(shù)中聲明時熄阻,只能在初始化塊以及屬性聲明中使用
class Person( name: String) //name只能在初始化塊以及屬性聲明中使用
5 如果這個主構(gòu)造函數(shù)沒有任何注解或者可見的修飾符,這個constructor{: .keyword }關(guān)鍵字可以被省略倔约。否則必須保留
class Person public @Inject constructor(name: String){
}
次構(gòu)造函數(shù)
1秃殉、次構(gòu)造函數(shù)不能有聲明 val 或 var
2、如果類有一個主構(gòu)造函數(shù)(無論有無參數(shù))浸剩,每個次構(gòu)造函數(shù)需要直接或間接委托給主構(gòu)造函數(shù)钾军,用this關(guān)鍵字
class Person(){
constructor(name: String):this() {
}
constructor(name: String, age: Int) : this(name) {
}
}
3、當(dāng)沒有主構(gòu)造參數(shù)時绢要,創(chuàng)建次構(gòu)造函數(shù)時吏恭,不需要this關(guān)鍵字
class Person(){
constructor(name: String){
}
}
繼承
1 如果子類有主構(gòu)造函數(shù),其可以(并且必須)用(基類型的)主構(gòu)造函數(shù)參數(shù)就地初始化重罪。
2 如果類沒有主構(gòu)造函數(shù)樱哼,那么每個次構(gòu)造函數(shù)必須 使super 關(guān)鍵字初始化其基類型,或委托給另個構(gòu)造函數(shù)做到這咦點剿配。另外不同的次構(gòu)造函數(shù)可以調(diào)用基類的不同構(gòu)造函數(shù)
3 Kotlin 需要顯式標(biāo)注可覆蓋的成員(我們稱之為開放)和覆蓋后的成員搅幅,標(biāo)記為 override 的成員本是開放的,也就是說呼胚,它可以在子類中覆蓋茄唐。如果你想禁止再次覆蓋,使final 關(guān)鍵字:
open class Base {
open fun v() {}
fun nv() {}
}
class Derived() : Base() {
override fun v() {}
}
4 屬性覆蓋與方法覆蓋類似蝇更,var 屬性可以覆蓋 val 屬性沪编,但反之則不行,可以在主構(gòu)造函數(shù)中使 override 關(guān)鍵字作為屬性聲明的一部分年扩。
interface Foo {
val count: Int
}
class Bar1(override val count: Int) : Foo
5 多繼承: 如果子類從它的直接超類繼承相同成員的多個實現(xiàn)蚁廓,它必須覆蓋這個成員并提供其自己的實現(xiàn)(也許繼承來的其中之)。 為了表示從哪個超類型繼承的實現(xiàn)常遂,我們使用由尖括號中超類型名限定的 super纳令,如 super<Base> :
open class A {
open fun f() { print("A") }
fun a() { print("a") }
}
interface B {
fun f() { print("B") } // 接成員默認(rèn)就是“open”的
fun b() { print("b") }
}
class C() : A(), B {
// 編譯器要求覆蓋 f():
override fun f() {
super<A>.f() // 調(diào)A.f()
super<B>.f() // B.f()
}
6 與 Java 或 C# 不同,在 Kotlin 中類沒有靜態(tài)方法克胳。在多數(shù)情況下平绩,它建議簡單地使用 包級函數(shù)。