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

可以在Kotlin中创建扩展构造函数吗?,kotlin,Kotlin,在其他语言(如Swift)中,可以创建添加新构造函数的函数扩展 大概是这样的: // base class class Whatever() { ... } // constructor method extension fun Whatever.constructor(potato: String) { setPotato(potato) } fun main(args: Array<String>) { println(Whatever("holi")

在其他语言(如Swift)中,可以创建添加新构造函数的函数扩展

大概是这样的:

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

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

fun main(args: Array<String>) {
    println(Whatever("holi"))
}
//基类
类(){
...
}
//构造函数方法扩展
有趣的东西。构造函数(土豆:字符串){
马铃薯(马铃薯)
}
趣味主线(args:Array){
println(无论什么(“holi”))
}

在Kotlin中有什么方法可以做到这一点吗?

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

class Foo() {
    ...
}

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

fun main(args: Array<String>){
    println(Foo(123))
}
class Foo(){
...
}
fun-Foo(stuff:Int):Foo=Foo().apply{setStuff(stuff)}
趣味主线(args:Array){
println(Foo(123))
}

与Swift不同,因为:

扩展是静态解析的。 扩展实际上并不修改它们扩展的类。通过定义 扩展时,您不会向类中插入新成员,而只是使 新函数可在此函数的变量上使用点表示法调用 类型。()


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


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

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)
}
类水果(变量名称:String=”“){
}
高级水果厂{
伴星{
趣味创作(名称:字符串):水果{
返回水果(){
this.name=“Tasty$name”
}
}
}
}
趣味主线(args:Array){
val orange=水果(“橙色”)
println(orange.name)
val apple=水果工厂。创建(“苹果”)
println(apple.name)
}
您可以使用嵌套的或作为扩展函数的其他构造函数来扩展工厂

输出:

橙色
美味的苹果


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

// 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"))
}
//基类
类(){
伴星{
}
}
//工厂扩建
有趣的东西。伴侣。土豆(土豆:串){
//马铃薯(马铃薯)
}
趣味主线(args:Array){
println(无论用什么土豆(“holi”))
}

唯一的问题是:要做到这一点,必须有一个
伴星
对象。

基于@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"))
}

另一种方法是仅对参数声明扩展函数(如果有许多扩展函数,则声明第一个扩展函数):

//基类
类(){
...
}
//延伸
有趣的字符串。toWhatever()=Whatever()。应用{setPotato(this)}
趣味主线(args:Array){
println(“holi.toWhatever())
}
优点:

  • 您可以避免声明一个空的同伴对象的麻烦
  • which
    类没有同伴且不是您的同伴时仍然可能,因此即使您需要,也无法添加同伴
  • 简洁惯用的方法

这不是模仿构造函数,而是工厂模式:)你是对的,但这有一点不同,你不需要调用factory.foo(123)。糖码anyway@WilliMentzel它模仿了客户端的构造函数:他们调用它的方式与调用构造函数的方式相同,不需要知道它是哪一个。@WilliMentzel对于这个特定的用法,我认为它非常好。当然,这只是我的观点。虽然这可以为用户模拟构造函数,但这样做也有缺点:
fun Int.Companion.setPotato(potato: String) {
    // ...
}
// base class
class Whatever() {
    ...
}

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

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