在像Swift这样的其他语言中,有可能创建一个添加新构造函数的函数扩展。
这样的事情:
// base class
class Whatever() {
...
}
// constructor method extension
fun Whatever.constructor(potato: String) {
setPotato(potato)
}
fun main(args: Array<String>) {
println(Whatever("holi"))
}
Kotlin有没有办法做到这一点?
答案 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())
}
优点:
Whatever
类没有伴侣并且不是您的伴侣时,仍然有可能,因此即使您愿意,也无法添加伴侣