主構(gòu)造方法和初始化語句塊
聲明一個主構(gòu)造方法
class User constructor(_nickname: String){<!-- 帶一個參數(shù)的主構(gòu)造方法-->
val nickname: String
init { <!--初始化語句塊-->
nickname = _nickname
}
}
在上面的例子中,由于主構(gòu)造方法中有限制,不能包含初始化代碼,因此需要使用初始化語句塊。
在這個例子中,也可以去掉constructor關(guān)鍵字
class User2 constructor(_nickname: String){
val nickname = _nickname
}
如果屬性用相應(yīng)的構(gòu)造方法參數(shù)來初始化,代碼可以通過把val關(guān)鍵字加在參數(shù)前的方式來進行簡化,這樣就可以替換類中的屬性定義
class User(val nickname:String)
可以向函數(shù)參數(shù)一樣為構(gòu)造方法參數(shù)聲明默認(rèn)值
class User(val nickname: String,val isSubscribed: Boolean = true)
如果一個類中具有父類,主構(gòu)造方法中同樣需要初始化父類
open class User(val nickname: String){...}
class TwitterUser(name:String) : User(name){...}
如果父類沒有提供任何的構(gòu)造方法,必須顯示地調(diào)用父類的構(gòu)造方法,即使它沒有任何的參數(shù)
open class Button
class RadioButton : Button()
不要讓類外部的代碼實例化它,可以將構(gòu)造方法標(biāo)記為private
class Secretive private constructor(){...}
用不同的方式初始化父類
當(dāng)需要重寫父類多個構(gòu)造方法時,需要聲明多個從構(gòu)造方法
class MyButton : View{
constructor(ctx:Context):this(ctx, null)<!--調(diào)用自己的構(gòu)造方法-->
constructor(ctx: Context,attr: AttributeSet?):super(ctx,attr) <!--調(diào)用父類的構(gòu)造方法-->
}
實現(xiàn)在接口中聲明的屬性
interface User {
val nickname: String
}
-
在子類的主構(gòu)造方法的參數(shù)前面加上
override關(guān)鍵字,表明這個屬性實現(xiàn)了來自于父類User的抽象屬性class PrivateUser(override val nickname: String) : User -
nickname屬性通過自定義getter的方式來實現(xiàn)class SubscribingUser(val email: String) : User { override val nickname: String get() = email.substringBefore("@") } 在初始化時將
nickname屬性與值關(guān)聯(lián)的方式來實現(xiàn)
class FaceBookUser(val accountId:Int) : User {
override val nickname = getFacebookName(accountId)
}
除了抽象屬性聲明外,接口還可以包含具有getter和setter的屬性
interface User {
val email: String
val nickname: String
get() = email.substringBefore("@")
}
這個接口包含抽象屬性email,同時nickname屬性有一個自定義的getter。第一個屬性必須在子類中重寫,第二個屬性是可以被繼承的。
通過getter或setter訪問支持字段
聲明一個可變屬性,并且在每次setter訪問時執(zhí)行額外的代碼
class User(val name: String){
var address: String = "unspecified"
set(value) {
println("Address was changed for $name: $address -> $value") <!--讀取支持字段的值-->
field = value <!--更新支持字段的值-->
}
}
val user = User("kangdongpu");
user.address = "HeBei,SJZ"
<!--輸出-->
Address was changed for kangdongpu: unspecified -> HeBei,SJZ
在setter的函數(shù)體中,使用了特殊的標(biāo)識符field來訪問支持字段的值。在getter中,只能讀取值;而在setter中,即能讀取也能修改它
修改訪問器的可見性
聲明一個具有private setter的屬性,讓其不能在類外部被修改
class LengthCounter {
var counter:Int = 0
private set <!--不能在類外部修改此屬性值,將setter的可見性改為private-->
fun addWord(word:String){<!--可在類內(nèi)部通過方法修改-->
counter+=word.length
}
}