# Kotlin 对象声明和表达式

> 原文： [https://www.programiz.com/kotlin-programming/object-singleton](https://www.programiz.com/kotlin-programming/object-singleton)

#### 在本文中，您将在示例的帮助下了解对象声明（单例）和对象表达式。

## 对象声明

单例是一种面向对象的模式，其中一个类只能有一个实例（对象）。

例如，您正在处理具有 SQL 数据库后端的应用。 您想创建一个连接池来访问数据库，同时为所有客户端重用相同的连接。 为此，您可以通过单例类创建连接，以便每个客户端获得相同的连接。

* * *

Kotlin 提供了一种使用对象声明功能创建单例的简单方法。 为此，使用了`object`关键字。

```kt
object SingletonExample {
    ... .. ...
    // body of class
    ... .. ...
}
```

上面的代码结合了一个类声明和该类的单个实例`SingletonExample`的声明。

对象声明可以包含属性，方法等。 但是，不允许它们具有构造器（这很有意义）。 **为什么？**

与普通类的对象类似，可以使用`.`表示法调用方法和访问属性。

* * *

### 示例：对象声明

```kt
object Test {
    private var a: Int = 0
    var b: Int = 1

    fun makeMe12(): Int {
        a = 12
        return a
    }
}

fun main(args: Array<String>) {
    val result: Int

    result = Test.makeMe12()

    println("b = ${Test.b}")
    println("result = $result")
}
```

运行该程序时，输出为：

```kt
b = 1
result = 12
```

* * *

对象声明可以像普通类一样从类和接口继承。

* * *

### 单例和依赖注入

对象声明有时会很有用。 但是，它们在与系统许多其他部分交互的大型软件系统中并不理想。

**推荐阅读**： [依赖注入&单例设计模式](https://stackoverflow.com/questions/2662842/dependency-injection-singleton-design-pattern)

* * *

## Kotlin 对象表达式

`object`关键字也可以用于创建称为匿名对象的匿名类的对象。 如果您需要创建一个对某些类或接口稍加修改而又不为其声明子类的对象，则可以使用它们。 例如 ，

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

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

（该示例摘自 [Kotlin 官方文档页面](https://kotlinlang.org/docs/reference/object-declarations.html)。）

在此，声明了扩展`MouseAdapter`类的匿名对象。该程序覆盖了`mouseClicked()`和`mouseEntered()`这两个`MouseAdapter`方法。

如有必要，可以为匿名对象分配名称，并将其存储在变量中。 例如，

```kt
val obj = object : MouseAdapter() {
    override fun mouseClicked(e: MouseEvent) {
        // ...
    }

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

* * *

### 示例：Kotlin 对象表达式

```kt
open class Person() {
    fun eat() = println("Eating food.")

    fun talk() = println("Talking with people.")

    open fun pray() = println("Praying god.")
}

fun main(args: Array<String>) {
    val atheist = object : Person() {
        override fun pray() = println("I don't pray. I am an atheist.")
    }

    atheist.eat()
    atheist.talk()
    atheist.pray()
}

```

运行该程序时，输出为：

```kt
Eating food.
Talking with people.
I don't pray. I am an atheist.
```

在这里，匿名对象存储在变量`atheist`中，该变量通过`pray()`方法实现了`Person`类。

* * *

如果要实现的类具有用于声明匿名对象的构造器，则需要传递适当的构造器参数。 例如，

```kt
open class Person(name: String, age: Int) {

    init {
        println("name: $name, age: $age")
    }

    fun eat() = println("Eating food.")
    fun talk() = println("Talking with people.")
    open fun pray() = println("Praying god.")
}

fun main(args: Array<String>) {
    val atheist = object : Person("Jack", 29) {
        override fun pray() = println("I don't pray. I am an atheist.")
    }

    atheist.eat()
    atheist.talk()
    atheist.pray()
}

```

运行该程序时，输出为：

```kt
name: Jack, age: 29
Eating food.
Talking with people.
I don't pray. I am an atheist.
```