類
類的定義
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 //僅在同一個(gè)文件中可見
protected //同一個(gè)文件中或子類可見
public //所有調(diào)用的地方都可見
internal //同一個(gè)模塊中可見
1 當(dāng)Kotlin中的類需要構(gòu)造函數(shù)時(shí),可以有一個(gè)主構(gòu)造函數(shù)和多個(gè)次構(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ù)中聲明時(shí),只能在初始化塊以及屬性聲明中使用
class Person( name: String) //name只能在初始化塊以及屬性聲明中使用
5 如果這個(gè)主構(gòu)造函數(shù)沒有任何注解或者可見的修飾符,這個(gè)constructor{: .keyword }關(guān)鍵字可以被省略。否則必須保留
class Person public @Inject constructor(name: String){
}
次構(gòu)造函數(shù)
1、次構(gòu)造函數(shù)不能有聲明 val 或 var
2、如果類有一個(gè)主構(gòu)造函數(shù)(無論有無參數(shù)),每個(gè)次構(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ù)時(shí),創(chuàng)建次構(gòu)造函數(shù)時(shí),不需要this關(guān)鍵字
class Person(){
constructor(name: String){
}
}
繼承
1 如果子類有主構(gòu)造函數(shù),其可以(并且必須)用(基類型的)主構(gòu)造函數(shù)參數(shù)就地初始化。
2 如果類沒有主構(gòu)造函數(shù),那么每個(gè)次構(gòu)造函數(shù)必須 使super 關(guān)鍵字初始化其基類型,或委托給另個(gè)構(gòu)造函數(shù)做到這咦點(diǎn)。另外不同的次構(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 多繼承: 如果子類從它的直接超類繼承相同成員的多個(gè)實(shí)現(xiàn),它必須覆蓋這個(gè)成員并提供其自己的實(shí)現(xiàn)(也許繼承來的其中之)。 為了表示從哪個(gè)超類型繼承的實(shí)現(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ù)。