Kotlin:抽象超类可以有抽象构造函数吗?

Kotlin:抽象超类可以有抽象构造函数吗?,kotlin,Kotlin,我刚刚写了这篇文章,就其内容而言,这很好: import com.github.salomonbrys.kotson.get import com.github.salomonbrys.kotson.int import com.github.salomonbrys.kotson.jsonObject import com.google.gson.JsonElement import com.google.gson.JsonObject abstract class BatchJobPaylo

我刚刚写了这篇文章,就其内容而言,这很好:

import com.github.salomonbrys.kotson.get
import com.github.salomonbrys.kotson.int
import com.github.salomonbrys.kotson.jsonObject
import com.google.gson.JsonElement
import com.google.gson.JsonObject

abstract class BatchJobPayload {
    abstract fun toJson(): JsonObject
}

class BookingConfirmationMessagePayload(val bookingId: Int) : BatchJobPayload() {
    constructor(payload: JsonElement) : this(payload["bookingId"].int)

    override fun toJson() = jsonObject(
        "bookingId" to bookingId
    )
}
但我想坚持,如果可能的话,所有扩展
BatchJobPayload
的类都要实现一个带有签名的二级构造函数
构造函数(payload:JsonElement):BatchJobPayload
,用于反序列化


BookingConfirmationMessagePayload
有这样一个构造函数,但这只是因为我把它放在那里,而不是因为
BatchJobPayload
坚持要它…

您不能强制执行超级构造函数,但可以强制工厂使用一个spawn方法,该方法返回
BatchJobPayload
的子类,这允许您确保类是可构造的

它看起来像这样:

class JsonObject // Included to make compiler happy

abstract class Factory<T> {
    abstract fun make(obj: JsonObject): T
}

abstract class Base {
    abstract fun toJson(): JsonObject
}


class A(val data:JsonObject):Base() {
    override fun toJson(): JsonObject {
        return JsonObject()
    }
}

class AFactory: Factory<A>() {
    override fun make(obj: JsonObject): A {
        return A(obj)
    }

}

fun main(args: Array<String>) {
    val dummyJson = JsonObject()

    var factory = AFactory()
    var instance = factory.make(dummyJson)

    println(instance)
}
classjsonobject//
抽象类工厂{
抽象趣味制作(obj:JsonObject):T
}
抽象类基{
抽象趣味toJson():JsonObject
}
类(val数据:JsonObject):Base(){
重写fun toJson():JsonObject{
返回JsonObject()
}
}
A类工厂:工厂(){
覆盖趣味制造(obj:JsonObject):A{
返回A(obj)
}
}
趣味主线(args:Array){
val dummyJson=JsonObject()
var factory=AFactory()
var instance=factory.make(dummyJson)
println(实例)
}

我想出了一个可行的选择,如下所示:

interface BatchJobPayload {
    fun toJson(): JsonObject
}

interface BatchJobPayloadDeserialize {
    operator fun invoke(payload: JsonElement): BatchJobPayload
}

class BookingConfirmationMessagePayload(val bookingId: Int) : BatchJobPayload {
    override fun toJson() = jsonObject(
        "bookingId" to bookingId
    )
}

class BookingConfirmationMessagePayloadDeserialize : BatchJobPayloadDeserialize {
    override operator fun invoke(payload: JsonElement) =
        BookingConfirmationMessagePayload(payload["bookingId"].int)
}
BookingConfirmationMessagePayloadDeserialize()(payload)
现在,您可以从
JsonElement
反序列化
BookingConfirmationMessagePayload
对象,如下所示:

interface BatchJobPayload {
    fun toJson(): JsonObject
}

interface BatchJobPayloadDeserialize {
    operator fun invoke(payload: JsonElement): BatchJobPayload
}

class BookingConfirmationMessagePayload(val bookingId: Int) : BatchJobPayload {
    override fun toJson() = jsonObject(
        "bookingId" to bookingId
    )
}

class BookingConfirmationMessagePayloadDeserialize : BatchJobPayloadDeserialize {
    override operator fun invoke(payload: JsonElement) =
        BookingConfirmationMessagePayload(payload["bookingId"].int)
}
BookingConfirmationMessagePayloadDeserialize()(payload)
(这里,
invoke
操作符只是一些语法上的糖分,可能接近钝角…)


事实上,我仍然更喜欢原始代码,它不那么冗长——将来需要对
BatchJobPayload
进行子类化的开发人员最初可能会忽略定义一个构造函数,该构造函数采用
JsonElement
,但一旦他们只有一个JSON字符串,需要将其转换为他们新课程的实例…

我认为你做不到。。如果给
BatchJobPayload
一个构造函数,所有的子类都必须调用这个超级构造函数,但我认为这并没有帮助让这两个构造函数都是必需的没有意义。如果您希望有人总是通过
bookingId
,为什么不完全删除默认构造函数呢?那么它有什么作用呢?Insead为它设置了一个默认值,也许?@Sourabh其目的是始终有两种方法来生成
BatchJobPayload
的子类:直接使用主构造函数,间接使用JSON字符串,这是在现有实例上调用
toJson
的结果。看,我无法让这个代码工作。我不确定您是否可以使用上面显示的类型参数在Koltin中构造一个对象:
返回一个(obj)
。@gtod我添加了一个主要方法来演示如何使用它,它在我这边成功运行,您面临什么样的问题?抱歉@jrtapsell,您是对的,我让它工作了:没问题,我应该包括从开始的主要方法,事实上我改变了定义。在
A
类A(val id:Int):Base(){
A工厂
中,覆盖现在是
override-fun-make(obj:JsonObject)=A(obj[“id”].Int)
。这是可行的,但因为通常
A
B
等类需要自己独特的构造函数,类型参数的意义是什么(你看到我自己的答案了吗?