非常有用的对象表达式
在java开发中,需要频繁声明很多回调接口
,这些回调接口
通常是内部
且一次性
, 我们经常会使用匿名的方式创建对象。而kotlin也支持这种方式。
在java中,我们经常会这么使用一个接口
interface ISay {
void sayHello();
}
ISay say = new ISay() {
@Override
public void sayHello() {
//TODO
}
};
在kotlin中,我们可以使用匿名类对象
解决这个问题,使用object
关键字代表一个匿名内部类型
,可以访问其作用域
中所有变量,上面的语言翻译过来可以是:
var say = object : AnonymousObjectTest.ISay {
override fun sayHello() {
TODO("not implemented")
}
}
而且kotlin支持多继承
的匿名类型
,超级牛逼
abstract class Listen(ear: Int) {
abstract fun listen()
}
var person =object:AnonymousObjectTest.ISay,Listen(2){
override fun listen() {
TODO("not implemented")
}
override fun sayHello() {
TODO("not implemented")
}
}
还有一种情况,我们也可以定义一个任意的匿名对象
而不额外声明任何的类,但是这个对象的作用范围只存在于作用域
内, 超过作用域
则无法访问定义的属性
fun foo() {
val adHoc = object {
var x: Int = 0
var y: Int = 0
}
print(adHoc.x + adHoc.y)
}
单例
kotlin可以非常方便的声明一个单例
, 我们可以通过object
声明一个全局的对象。建议这里理解成对象
,不要理解为类
,否则在使用上会与类的静态方法
产生差异。
abstract class Listen(ear: Int) {
abstract fun listen();
}
object SingleInstace : Listen(2) {
override fun listen() {
System.out.println("hear the world!!")
}
}
fun main(args: Array<String>) {
SingleInstace.listen()
}
那么静态类和静态方法应该如何定义呢?我们马上开讲
静态类与静态方法
kotlin可以使用伴生对象
定义静态对象与静态方法。类
和它的伴生对象
可以相互访问私有特性,使用companion object
关键字修饰, 它的初始化是在相应的类被加载(解析)
时进行的
class CompanionClassSimple {
val a = 1
init {
println("加载类实例") //初始化测试:在类实例化时被加载,加载时机晚于其伴生对象
}
companion object {
init {
println("加载伴生对象") //初始化测试:伴生对象将在类被加载时创建,最先打印
}
var b = 1 //静态属性 相当于 static int b = 1
val c=2 //只读静态属性 相当于final static int b = 1
fun plus(x: Int): Int { //静态方法:相当于 public static int plus(int x)
return x + b
}
}
}
fun main(args: Array<String>) {
var foo = CompanionClassSimple()
// foo.b 是非法调用,伴生对象的属性无法被类实例调用
//foo.plus(1) 是非法调用,伴生对象的属性无法被类实例调用
println("像java一样调用静态对象:${CompanionClassSimple.b}")
println("像java一样调用静态方法:${CompanionClassSimple.plus(1)}")
//全局唯一性
Thread(object : Runnable {
override fun run() {
while (true) {
Thread.sleep(1_000)
CompanionClassSimple.b++ //每一秒新增一次
}
}
}).start()
Thread(object : Runnable {
override fun run() {
while (true) {
Thread.sleep(2_000)
System.out.println(CompanionClassSimple.b) //每两秒打印一次
}
}
}).start();
readLine()
}
伴生对象
的成员看起来像其他语言的静态成员
,在运行时他们仍然是真实对象
的实例成员
该对象实现可以实现接口,例如
companion object : Runnable()