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
等类需要自己独特的构造函数,类型参数的意义是什么(你看到我自己的答案了吗?