对象表达式和申明:
有些时候咱们须要建立一个轻量修改的类,没有明确申明一个新的超类,Java处理这种状况是用一个异步内部类实现,kotlin则用对象表达式和对象申明的概念来实现。
对象表达式:
建立一个继承某些类的异步类对象,咱们这样写:
```
window.addMouseListener(object : MouseAdapter() {
override fun mouseClicked(e: MouseEvent) {
// ...
}html
override fun mouseEntered(e: MouseEvent) {
// ...
}
})
```
若是超类有一个构造函数,那么必须传递一个合适构造参数,某些超类应该在冒号以后写成为一个逗号分开的列表
```
open class A(x: Int) {
public open val y: Int = x
}java
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)
}
```
这个有点像Java中的匿名类,并把索引给参数adHoc,里面定义了两个属性值,经过.操做进行取值。ide
注意:异步对象能够在仅仅是一个本地私有申明的时候用来作看成一个类,若是你使用一个异步对象做为公共函数返回值的类型或者公共属性的返回类型,那么这个实际类型
式函数或者属性将被申明这个异步对象的超类或者返回Any,若是你没有申明任何超类,添加在异步对象的成员将不可被访问
```
class C {
// Private function, so the return type is the anonymous object type
private fun foo() = object {
val x: String = "x"
}函数
// Public function, so the return type is Any
fun publicFoo() = object {
val x: String = "x"
}htm
fun bar() {
val x1 = foo().x // Works
val x2 = publicFoo().x // ERROR: Unresolved reference 'x'
}
}
```
仅仅想Java的异步内部类,代码在对象表达式中能够访问外部块(不像java,这没有限制为final变量)
```
fun countClicks(window: JComponent) {
var clickCount = 0
var enterCount = 0对象
window.addMouseListener(object : MouseAdapter() {
override fun mouseClicked(e: MouseEvent) {
clickCount++
}继承
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) {
// ...
}
}
```
标记:对象申明没有本地,可是他们能够嵌套进其余对象申明或者非内部类
同伴对象:
在类中的对象申明能够用companion标记
```
class MyClass {
companion object Factory {
fun create(): MyClass = MyClass()
}
}
```
同伴对象的成员能够被调用经过使用简单的类名字当作修饰
```
val instance = MyClass.create()
```
同伴对象的名字能够被省略,在Companion将被使用的例子中
```
class MyClass {
companion object {
}
}
val x = MyClass.Companion
```
记录:即便同伴对象的成员看起来像静态成员,在运行时,这些真实对象的陈成员仍然存在,而且可能好比继承接口,:
```
interface Factory<T> {
fun create(): T
}
class MyClass {
companion object : Factory<MyClass> {
override fun create(): MyClass = MyClass()
}
}
```
然而在JVM中你能够拥有同伴对象的成员当作静态方法和域生产。若是你使用@JvmtSatic,[Java interoperability](http://kotlinlang.org/docs/reference/java-to-kotlin-interop.html#static-fields)
在对象表达式和申明中的语义区别: 这有一个重点语义区别: 一、对象表达式能够在须要使用的时候被当即执行 二、对象申明在咱们第一次访问的时候进行延迟申明 三、一个同伴对象当当前类被加载被初始化,匹配的是Java静态初始化语义