2017-10-05 33 views
5

Swiftのような他の言語では、新しいコンストラクタを追加する関数拡張を作成する可能性があります。このようなKotlinで拡張コンストラクタを作成することは可能ですか?

何か:

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

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

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

Kotlinでこれを行うための任意の手段はありますか? 、

答えて

9

は公式の「コンストラクタのための機能拡張」がないようだが、あなたは

class Foo() { 
    ... 
} 

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

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

これはコンストラクタを模倣するものではなく、ファクトリパターンです。 –

+3

これは違いますが、これは違いがあり、Factory.foo(123)を呼び出す必要はありません。とにかく砂糖コード – Aracem

+2

@WilliMentzelこれはクライアントのコンストラクタを模倣します。コンストラクタと同じ方法であり、コンストラクタと同じ方法であり、それがどれであるかを知る必要はありません。 –

6

は、スウィフトに好きないコンストラクタを模倣したパッケージ・メソッドを作成することができますので:

拡張機能静的に解決されます。 エクステンションは実際に拡張するクラスを変更しません。 拡張を定義すると、新しいメンバーをクラスに挿入するのではなく、 型の変数のドット表記で新しい関数を呼び出し可能にするだけです。 (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) 
} 

あなたは工場を拡張することができます。


ない場合は、古典的なファクトリパターンを使用します。

出力:

オレンジ
おいしいアップル

4

あなたがこれを行うことはできません。あなたはしかし何をすることができます。

// 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オブジェクトを拡張companionオブジェクトを、これを行うために存在する必要があります。

+0

もしもコンパニオンオブジェクトがあれば、これは行く方法です! +1 –

関連する問題