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 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
所有类BatchJobPayload
实现一个带有签名constructor(payload: JsonElement): BatchJobPayload
的二级构造constructor(payload: JsonElement): BatchJobPayload
,它将用于反序列化。
BookingConfirmationMessagePayload
有这样的构造函数,但只是因为我把它放在那里,不是因为BatchJobPayload
坚持它…
我提出了一个可行的选择,如下所示:
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) }
现在,您可以从JsonElement
反序列化BookingConfirmationMessagePayload
对象,如下所示:
BookingConfirmationMessagePayloadDeserialize()(payload)
( invoke
操作符只是这里的一些语法糖,它们可能会接近于钝角…)
实际上,我仍然更喜欢那些不那么冗长的原始代码 – 将来开发者需要BatchJobPayload
可能最初忽略了定义一个带有JsonElement
的构造函数,但是一旦他们只有一串JSON,他们肯定会意识到它们的省略。他们需要变成他们新班的一个例子
你不能强制执行一个超级构造函数,但是你可以使用spawn方法强制执行返回BatchJobPayload
子类的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) }