本文我们需要了解几个点。
①object与any的区别?
②private跟非private返回值的区别?
③Kotlin中单例模式怎么实现?又如何调用?
④伴生对象什么时候产生?可以如何调用?
⑤对象表达式、声明对象、伴生对象 初始化的时机?
本节目录不重要。带着这些问题就可以了。
Kotlin的对象表达式,再一次简化了,对某个类做轻微改动时,且不需要去声明一个新的子类。
与java一样,或继承、或实现、或通过构造函数传值给其参数。
window.addMouseListener(object : MouseAdapter() {
override fun mouseClicked(e: MouseEvent) { /*……*/ }
override fun mouseEntered(e: MouseEvent) { /*……*/ }
})
知识点复习
理解一下Kotlin中,object与any的区别
我们看一段英文解析,或许更加清晰。
Kotlin compiler treats kotlin.Any and java.lang.Object as two different types,
but at runtime they are represented with the same java.lang.Object class.
编译器认为Any和Object是不同的类型;但是在运行时,Any和Object表现出来是一样的。
这也是Kotlin可以和Java互通的一个提现。运行时,我们都一样的。
解析
private fun foo() = object {
val x: String = "x"
}
把冒号 后面的去掉
class C {
// 私有函数,所以其返回类型是匿名对象类型
private fun foo() = object {
val x: String = "x"
}
// 公有函数,所以其返回类型是 Any
fun publicFoo() = object {
val x: String = "x"
}
fun bar() {
val x1 = foo().x // 没问题
val x2 = publicFoo().x // 错误:未能解析的引用“x”
}
}
注意
留意上述范例中的 注释部分
通过对象声明,可以获得一个单例单例单例单例 重要的事情说三遍
object DataProviderManager {
fun registerDataProvider(provider: DataProvider) {
// ……
}
val allDataProviders: Collection
get() = // ……
}
这就是对象声明。
仿佛是你声明了一个变量一样
DataProviderManager.registerDataProvider(……)
单例的调用不用getInstance了。砍砍砍,砍代码量啊
var data1 = DataProviderManager
var data2 = DataProviderManager
data1.name = "test"
print("data1 name = ${data2.name}")
//这里data1.name 和data2.name是一样的
注意
object声明的单例,只能通过类名来访问!!!
Kotlin的单例,避免了getInstance,直接调用。
砍砍砍,砍代码量啊
class Engineer {
var name = "wangxueming"
object Info {
var sex = "man"
fun showName(){
print{"desk legs $name"} // 错误,不能访问到外部类的方法和变量
}
}
}
fun main(args: Array) {
var wxm = Engineer()
wxm.Info.sex // 错误,不能通过外部类的实例访问到该对象
Engineer.Info.sex // 正确
}
通过object声明的对象,是单例,而且!只能!通过 类名 范文。不得不说,这避免了不少麻烦事。
明摆的事情!我访问单例,肯定就是那么个实例。
用 companion 关键字标记
与外部类关联在一起!!!如影随形
可以直接通过外部类访问到对象的内部元素
class MyClass {
companion object Factory {
fun create(): MyClass = MyClass()
}
}
val instance = MyClass.create() // 访问到对象的内部元素
也可以这样
class MyClass {
companion object {
}
}
val x = MyClass.Companion
注意
总体来说,在Kotlin中,通过object实现了单例,并简化了单例模式下实例的调用方式;
通过伴生对象,解决了部分的 初始化需求,但是,又在一些情况下,弱化伴生对象的存在(companion object修饰的类名可以不写)。
将减少代码量,作为最高意志。