【问题标题】:Why would you use a Kotlin companion object rather than an initializer block for creation?为什么要使用 Kotlin 伴生对象而不是初始化程序块来创建?
【发布时间】:2019-08-14 05:51:54
【问题描述】:

#37 Kotlin Tutorial | Companion Object | Factory Pattern 表示在创建复杂的类时可以使用 Kotlin 伴生对象。

Kotlin Primary Constructor and Initializer Blocks 展示了如何在类中使用 Kotlin 初始化程序块。

fun main(args: Array<String>) {
    val person1 = Person("joe", 25)
}
class Person(fName: String, personAge: Int) {
    val firstName: String
    var age: Int
    // initializer block
    init {
        firstName = fName.capitalize()
        age = personAge
        println("First Name = $firstName")
        println("Age = $age")
    }
}

为什么要使用伴随对象而不是初始化块?

关于这个问题,我对Java没有兴趣。

【问题讨论】:

  • 您说您对 Java 不感兴趣,但论点几乎相同,并且已经针对 Java 案例进行了充分讨论。

标签: kotlin constructor


【解决方案1】:

这种在构造函数(或 Kotlin 中的初始化块)上考虑静态工厂方法(又名 Kotlin 中的伴生对象)的做法是从 Java 世界借用的。

Java 中静态工厂方法和构造函数之间的区别与 Kotlin 中伴随对象和 init 块之间的区别几乎相同。

Here's a Medium article 巧妙地描述了伴随对象的优点。总结一下:

  1. 与构造函数不同,它们有名称
  2. 与构造函数不同,它们不需要在每次调用时都创建一个新对象
  3. 与构造函数不同,它们可以返回其返回类型的任何子类型的对象
  4. 它们减少了创建参数化类型实例的冗长性

编辑:添加了 AjahnCharles 的评论,因为它是一个有效的用例。

  1. 它们可以返回一个空对象,从而表明为创建对象传递的参数无效。 ()

与所有设计模式一样,伴随对象也有缺点:

  1. 它们不能用于子类构造
  2. 它们不易与其他静态方法区分开来

【讨论】:

  • 我已经澄清了这个问题,因为我对 Java 不感兴趣。 (文章:Kotlin 中的有效 Java...)。
  • 相同的点是有效的,主要是(除了名字,我想)。这是通常的静态与实例考虑。只有一个(静态)伴生对象;代码运行一次。为每个创建的实例运行 init 块中的代码。
  • 我要补充一点,工厂方法可以返回一个可空值,让您有机会彻底拒绝无效输入。
【解决方案2】:

工厂方法背后的一般思想是,您对工厂方法有一些输入,执行一些逻辑,然后有“输出”,即对象构造函数的必要参数。

当你只有一个工厂方法时,使用它的主要优点是它让你的类只公开一个主构造函数,它显示你的类需要的所有东西和你的类保留的所有东西。导出所有这些属性的逻辑在别处。我个人认为这很好,但不可否认,这不是偏爱工厂方法的一个非常充分的理由。

然而,一旦你有两个不同的工厂方法,使用初始化块的计划就变得不可能了。即使你创建了一个辅助构造函数,你的类的任何构造函数都会执行所有init 块......所以没有办法使用初始化器来拥有两个“独立”的工厂。

以下是一个非常人为的示例,但它确实展示了仅使用构造函数和init 块不可能实现的行为:

class Example(val text: String) {

    companion object {

        fun firstFactory(): Example {
            println("you called the first factory method")
            return Example("first")
        }

        fun secondFactory(): Example {
            println("you called the second factory method")
            return Example("second")
        }
    }
}

【讨论】:

    猜你喜欢
    • 2021-11-23
    • 1970-01-01
    • 1970-01-01
    • 2017-03-13
    • 2021-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-11
    相关资源
    最近更新 更多