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 реализуют вторичный конструктор с 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) } 

Теперь вы можете десериализовать объект BookingConfirmationMessagePayload из JsonElement следующим образом:

 BookingConfirmationMessagePayloadDeserialize()(payload) 

(Оператор invoke – это просто какой-то синтаксический сахар здесь, который может оказаться на тупых …)

На самом деле я по-прежнему предпочитаю оригинальный код, который является менее подробным. Разработчик, нуждающийся в подклассе BatchJobPayload в будущем, может вначале пренебречь определением конструктора, который принимает JsonElement но они наверняка осознают свое упущение, если у них есть только строка JSON, которая они должны превратиться в экземпляр своего нового класса …

Вы не можете применять супер-конструктор, но вы можете иметь фабрики с принудительным 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) } 
Intereting Posts
Метод автоматической реализации Kotlin Android Список несоответствий типа Kotlin <Any> и List <Comparable <{com.cognitect.transit.Symbol & com.cognitect.transit.Keyword}>?> Я хочу, чтобы каждый элемент массива каждого массива отображался в виде единого кадра Как я могу написать идиоматический код kotlin, который перебирает подпроцесс и обрабатывает его вывод? Лотские свойства и значения Kotlin сброшены: сбрасываемый ленивый делегат Преобразование кода создателя Java Parcel в Kotlin Не удалось настроить обновление плагина kotlin? Не удалось выполнить синхронизацию проекта Gradle, Котлин как скомпилировать kotlin в веб-проекте eclipse maven Log4j2 не работает с файлом конфигурации json Перекрестные ссылки в параметрах типа API разработчика Google Play – 400 Недопустимое значение – InAppPurchases Kotlin Kapt: java.lang.IllegalStateException: endPosTable уже установлен используя Котлин с Грейдлом Как опустить параметры лямбда в Котлин?