是否可以在Kotlin中创建扩展构造函数?

时间:2017-10-05 09:56:48

标签: kotlin

在像Swift这样的其他语言中,有可能创建一个添加新构造函数的函数扩展。

这样的事情:

// base class
class Whatever() {
    ...
}

// constructor method extension
fun Whatever.constructor(potato: String) {
    setPotato(potato)
}

fun main(args: Array<String>) {
    println(Whatever("holi"))
}

Kotlin有没有办法做到这一点?

5 个答案:

答案 0 :(得分:17)

似乎没有官方的“构造函数的函数扩展”,但是你可以创建一个模仿构造函数的包方法

class Foo() {
    ...
}

fun Foo(stuff: Int): Foo = Foo().apply {setStuff(stuff)}

fun main(args: Array<String>){
    println(Foo(123))
}

答案 1 :(得分:9)

不喜欢Swift,因为:

  

扩展程序已静态解决。   扩展实际上并不修改它们扩展的类。通过定义   扩展,您不会将新成员插入到类中,而只是生成   新函数可以使用点符号对此变量进行调用   类型。 (Source

如果目标类中定义了随播广告对象,请使用s1m0nw1's approach。优点是您可以在没有目标类的实例(静态)的情况下调用扩展函数。

如果不是,请使用经典的工厂模式:

class Fruit(var name: String = "") {
}

class FruitFactory {
    companion object {
        fun create(name: String): Fruit {
            return Fruit().apply {
                this.name = "Tasty $name"
            }
         }
    }
}

fun main(args: Array<String>) {
    val orange = Fruit("Orange")
    println(orange.name)

    val apple = FruitFactory.create("Apple")
    println(apple.name)
}

您可以根据需要使用嵌套或扩展函数的其他构造函数扩展Factory。

输出:

  


  美味的苹果

答案 2 :(得分:7)

你不能这样做。您可以做什么:使用工厂方法扩展类的companion对象:

// base class
class Whatever() {
    companion object {

    }

}

// factory extension
fun Whatever.Companion.withPotato(potato: String) {
    //setPotato(potato)
}

fun main(args: Array<String>) {
    println(Whatever.withPotato("holi"))
}

唯一的问题:必须存在companion对象才能执行此操作。

答案 3 :(得分:0)

基于@ s1m0nw1解决方案,我可以将其调整为更类似于覆盖运算符invoke所需的OP。

// base class
class Whatever() {
    companion object {
        fun setPotato(potato: String)
    }
}

operator fun Whatever.Companion.invoke(potato: String) {
    setPotato(potato)
}

fun main(args: Array<String>) {
    println(Whatever("holi"))
}

请记住,它仍需要在基类中使用伴侣对象。如果您不能编辑基类的源代码(如果是kotlin框架类或第三方类),并且它已经具有要向其中添加新方法的伴侣对象,则可以始终使用扩展功能:< / p>

fun Int.Companion.setPotato(potato: String) {
    // ...
}

答案 4 :(得分:0)

另一种选择是只在参数上声明一个扩展函数(如果有很多,则声明第一个):

// base class
class Whatever() {
    ...
}

// extension
fun String.toWhatever() = Whatever().apply { setPotato(this) }

fun main(args: Array<String>) {
    println("holi".toWhatever())
}

优点:

  • 您可以避免声明一个空的Companion对象的麻烦
  • Whatever类没有伴侣并且不是您的伴侣时,仍然有可能,因此即使您愿意,也无法添加伴侣
  • 紧凑惯用的方法