主構(gòu)造方法和初始化語(yǔ)句塊
聲明一個(gè)主構(gòu)造方法
class User constructor(_nickname: String){<!-- 帶一個(gè)參數(shù)的主構(gòu)造方法-->
val nickname: String
init { <!--初始化語(yǔ)句塊-->
nickname = _nickname
}
}
在上面的例子中衬以,由于主構(gòu)造方法中有限制,不能包含初始化代碼校摩,因此需要使用初始化語(yǔ)句塊看峻。
在這個(gè)例子中,也可以去掉constructor
關(guān)鍵字
class User2 constructor(_nickname: String){
val nickname = _nickname
}
如果屬性用相應(yīng)的構(gòu)造方法參數(shù)來(lái)初始化衙吩,代碼可以通過(guò)把val
關(guān)鍵字加在參數(shù)前的方式來(lái)進(jìn)行簡(jiǎn)化互妓,這樣就可以替換類中的屬性定義
class User(val nickname:String)
可以向函數(shù)參數(shù)一樣為構(gòu)造方法參數(shù)聲明默認(rèn)值
class User(val nickname: String,val isSubscribed: Boolean = true)
如果一個(gè)類中具有父類,主構(gòu)造方法中同樣需要初始化父類
open class User(val nickname: String){...}
class TwitterUser(name:String) : User(name){...}
如果父類沒(méi)有提供任何的構(gòu)造方法坤塞,必須顯示地調(diào)用父類的構(gòu)造方法冯勉,即使它沒(méi)有任何的參數(shù)
open class Button
class RadioButton : Button()
不要讓類外部的代碼實(shí)例化它,可以將構(gòu)造方法標(biāo)記為private
class Secretive private constructor(){...}
用不同的方式初始化父類
當(dāng)需要重寫(xiě)父類多個(gè)構(gòu)造方法時(shí)摹芙,需要聲明多個(gè)從構(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)造方法-->
}
實(shí)現(xiàn)在接口中聲明的屬性
interface User {
val nickname: String
}
-
在子類的主構(gòu)造方法的參數(shù)前面加上
override
關(guān)鍵字灼狰,表明這個(gè)屬性實(shí)現(xiàn)了來(lái)自于父類User
的抽象屬性class PrivateUser(override val nickname: String) : User
-
nickname
屬性通過(guò)自定義getter
的方式來(lái)實(shí)現(xiàn)class SubscribingUser(val email: String) : User { override val nickname: String get() = email.substringBefore("@") }
在初始化時(shí)將
nickname
屬性與值關(guān)聯(lián)的方式來(lái)實(shí)現(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("@")
}
這個(gè)接口包含抽象屬性email
浮禾,同時(shí)nickname
屬性有一個(gè)自定義的getter
交胚。第一個(gè)屬性必須在子類中重寫(xiě)份汗,第二個(gè)屬性是可以被繼承的。
通過(guò)getter
或setter
訪問(wèn)支持字段
聲明一個(gè)可變屬性蝴簇,并且在每次setter
訪問(wèn)時(shí)執(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)識(shí)符field
來(lái)訪問(wèn)支持字段的值。在getter
中军熏,只能讀取值轩猩;而在setter
中,即能讀取也能修改它
修改訪問(wèn)器的可見(jiàn)性
聲明一個(gè)具有private setter
的屬性荡澎,讓其不能在類外部被修改
class LengthCounter {
var counter:Int = 0
private set <!--不能在類外部修改此屬性值均践,將setter的可見(jiàn)性改為private-->
fun addWord(word:String){<!--可在類內(nèi)部通過(guò)方法修改-->
counter+=word.length
}
}