您的位置:首页 > 其它

Kotlin学习笔记3-11 类和对象-对象

2018-01-31 14:17 465 查看

对象表达式和对象声明

Kotlin官网:Classes and Objects-Objects

对于需要微调一些类,无需继承,类似于Java中的匿名内部类,Kotlin提供对象表达式和对象声明的形式。

对象表达式

创建一个继承一个或多个类的匿名类对象:

window.addMouseListener(object : MouseAdapter() {
override fun mouseClicked(e: MouseEvent) {
// ...
}

override fun mouseEntered(e: MouseEvent) {
// ...
}
})


继承有构造函数的类,必须选择一个调用;

继承多个类使用逗号分隔:

open class A(x: Int) {
public open val y: Int = x
}

interface B {...}

val ab: A = object : A(1), B {
override val y = 15
}


对于仅声明一个对象,不继承其他类的情况:

fun foo() {
val adHoc = object {
var x: Int = 0
var y: Int = 0
}
print(adHoc.x + adHoc.y)
}


匿名对象只在局部(local)和内部(private)有效。在外部使用,例如作为方法的返回值或是public成员,只能作为父类被使用,没有显式声明的为Any。在匿名对象中添加的成员无法被访问到的。

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  // 由于公开的函数返回类型为Any,无法访问到对象表达式的成员
}
}


类似于Java中匿名内部类可以访问外部成员,Kotlin的对象表达式也可以访问外部作用域中的成员,而且不受“必须final”的限制。

fun countClicks(window: JComponent) {
var clickCount = 0
var enterCount = 0

window.addMouseListener(object : MouseAdapter() {
override fun mouseClicked(e: MouseEvent) {
clickCount++ //外部成员不要求为final
}

override fun mouseEntered(e: MouseEvent) {
enterCount++
}
})
// ...
}


对象声明

Kotlin中可以使用对象声明的方式轻松实现单例模式:

object DataProviderManager {
fun registerDataProvider(provider: DataProvider) {
// ...
}

val allDataProviders: Collection<DataProvider>
get() = // ...
}


对象声明的格式为
object
+名字。

类似于变量声明,对象声明不是表达式,不能用来赋值(不能写在赋值语句右边)

使用对象声明:

DataProviderManager.registerDataProvider(...)


对象声明可以继承其他类:

object DefaultListener : MouseAdapter() {
override fun mouseClicked(e: MouseEvent) {
// ...
}

override fun mouseEntered(e: MouseEvent) {
// ...
}
}


注意:对象声明不能作为局部成员(例如写在函数内),可以嵌套在其他对象声明和非内部类(non-inner)中

伴生对象

使用
companion
关键字标记的对象声明

class MyClass {
companion object Factory {
fun create(): MyClass = MyClass()
}
}


调用伴生对象成员的格式和Java中调用静态成员的格式相同,类名.成员:

val instance = MyClass.create()


伴生对象的名字可以省略,此时为默认值”Companion”

class MyClass {
companion object {
}
}

val x = MyClass.Companion


伴生对象的使用格式和其他语言的静态成员使用格式类似,但是Kotlin中伴生对象是实例,伴生对象的成员都是实例成员,可以实现接口:

interface Factory<T> {
fun create(): T
}

class MyClass {
companion object : Factory<MyClass> {
override fun create(): MyClass = MyClass()
}
}


在JVM上可以使用
@JvmStatic
注解,使伴生对象成员生成为静态成员。详情见8-2Java中调用Kotlin

对象表达式和对象声明的区别

对象表达式是立刻执行的

对象声明是延迟初始化的,在第一次被访问时初始化

伴生对象在类被加载时初始化(相当于Java的静态初始化)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Kotlin