class A private constructor() {
companion object {
val instance: A by lazy { A() }
}
}
或者
class App : Application() {
companion object {
lateinit var instance: App
private set
}
override fun onCreate() {
super.onCreate()
instance = this
}
}
- Kotlin中的繼承
例子:
interface XYHolder {
val x: Int
val y: Int
}
方法1 繼承interface:
data class XY(override val x: Int, override val y: Int) : XYHolder
方法2使用代理:
data class B(val a: Int, private val xyh: XYHolder) : XYHolder by xyh
方法3 使用抽象類:
abstract class Resource (var name : String, var age : Int ){
abstract var addr : String
abstract val weight : Float
abstract var id: Long
abstract var location: String
}
data class Book(name : String, age : Int, var no : String, var score : Int, override var addr: String, override val weight: Float) (
override var id: Long = 0,
override var location: String = "",
var isbn: String
) : Resource()
方法4 如果父類構造方法沒有入參:
sealed class Either<out L, out R> {
data class Left<out L, out R>(val value: L) : Either<L, R>()
data class Right<out L, out R>(val value: R) : Either<L, R>()
}
- 對象表達式饶碘,對象聲明和伴隨對象的區(qū)別
對象表達式在使用的地方被立即執(zhí)行目尖。 對象聲明是延遲加載的, 在第一次使用的時候被初始化扎运。 伴生對象所在的類被加載瑟曲,伴生對象被初始化,與Java靜態(tài)成員類似豪治,雖然本質上 伴隨對象是真實對象的實例洞拨。
伴隨對象聲明時可以不指定對象名稱,對象聲明需要指定對象名字负拟。 - 當函數可能被其他模塊多次調用烦衣,并且代碼為10 行以下時,
用inline關鍵字可以提高代碼運行效率。
而內聯(lián)一個相當大的函數將顯著增加編譯后的代碼行數』ㄒ鳎現(xiàn)代處理器由于更好的利用了指令緩存, 小巧的代碼往往執(zhí)行更快秸歧。
- Kotlin與RxJava Retrofit結合使用時,發(fā)現(xiàn)雖然Observable.subscribe方法的onError方法參數的入參error標明是Throwable!衅澈,但網絡不好的時候键菱,error可能為null。
解決方法是使用error? 而不是error今布,如下所示:
ServiceGenerator.createService(LiveAPI::class.java)
.getRoomList(category.id,pageNumber)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ result ->
// 處理網絡返回的數據
}, { error ->
// 處理出錯的情況
error?.printStackTrace() // 使用error?经备, 因為error可能為null
})
- 協(xié)變與逆變
** 協(xié)變
List<out T>
val doubleList: List<Double> = listOf(1.0, 2.0)
val numberList: List<Number> = doubleList
out 聲名協(xié)變的形參T,表示List<Base> 是 List<Derived> 的超類
協(xié)變用于生產者的情況部默,即形參T在此類中的方法中只能作為返回值(作為入參要加UnsafeVariance注解)侵蒙,表示只能被讀取。
用現(xiàn)實生活舉例:一家生產羊肉的工廠是一家生產肉的工廠
肉商 = 羊肉商 這樣的賦值是正確的甩牺,肉是形參蘑志,廠商是類
** 逆變
Comparable<in T>
interface Comparable<in T> {
operator fun compareTo(other: T): Int
}
fun demo(x: Comparable<Number>) {
x.compareTo(1.0) // 1.0 has type Double, which is a subtype of Number
// Thus, we can assign x to a variable of type Comparable<Double>
val y: Comparable<Double> = x // OK!
}
in 聲名逆變的形參T,表示Comparable<Derived> 是Comparable<Base>的超類
逆變用于消費者的情況贬派,即形參T在此類中的方法中只能作為入參(作為返回值要加UnsafeVariance注解)急但,表示只能被輸入。
用現(xiàn)實生活舉例:一個能吃肉的人是一個能吃羊肉的人
能吃羊肉的人 = 能吃肉的人
這樣的賦值是正確的搞乏,肉是形參波桩,人是類
總結:
PECS: Producer Extends,Consumer Super
Producer out请敦,Consumer in
如果既是生產者也是消費者镐躲,就兩個修飾符都不能用了