2017-10-05 5 views
5

In anderen Sprachen wie Swift gibt es die Möglichkeit, eine Funktionserweiterung zu erstellen, die einen neuen Konstruktor hinzufügt.Ist es möglich, Erweiterungskonstruktoren in Kotlin zu erstellen?

Etwas wie folgt aus:

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

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

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

Gibt es Mittel, um dies in Kotlin zu tun?

Antwort

9

scheint, dass es keine offizielle „Funktionserweiterung für Konstrukteure“, aber Sie können ein Paket-Methode erstellen, die einen Konstruktor imitiert

class Foo() { 
    ... 
} 

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

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

Dies imitiert nicht den Konstruktor, es ist das Fabrikmuster :) –

+3

Sie haben Recht, aber das hat einen Unterschied, müssen Sie Factory.foo (123) nicht aufrufen. Sugar Code auf jeden Fall – Aracem

+2

@WilliMentzel Es ahmt einen Konstruktor für die Clients nach: Sie nennen es genauso wie sie einen Konstruktor und müssen nicht wissen, was es ist. –

6

Nicht in Swift mögen, weil:

Extensions werden statisch aufgelöst. Erweiterungen ändern Klassen, die sie erweitern, nicht wirklich. Wenn Sie eine Erweiterung definieren, fügen Sie keine neuen Member in eine Klasse ein, sondern machen lediglich neue Funktionen, die mit der Punktnotation auf Variablen dieses Typs aufgerufen werden können. (Source)


Wenn ein Begleitobjekt in Ihrer Zielklasse definiert ist, geht mit s1m0nw1's approach. Der Vorteil ist, dass Sie die Erweiterungsfunktion ohne eine Instanz (statisch) der Zielklasse aufrufen können.


Wenn nicht, verwenden Sie ein klassisches Werk Muster:

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) 
} 

Sie können die Fabrik erweitern, wie Sie mit weiteren Konstrukteure wollen entweder verschachtelte oder als Erweiterungsfunktionen.

Ausgang:

orange
Leckere Apfel

4

Sie können dies nicht tun. Was Sie aber tun können: Erweitere companion Objekt einer Klasse mit einem Factory-Methode:

// 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")) 
} 

Das einzige Problem: Ein companion Objekt hat existent sein, dies zu tun.

+0

wenn es ein begleitendes objekt gibt, ist dies der weg! +1 –

Verwandte Themen