2017-10-05 108 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")) 
} 

是否有任何手段在科特林做到這一點?

回答

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

你不能做到這一點。你雖然可以做什麼:一個工廠方法擴展一個類的對象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對象必須是實際存在的做到這一點。

+0

如果有伴侶對象,這是要走的路! +1 –