У меня есть набор классов данных, которые разделяют некоторые общие поля. Поэтому в идеале я хотел бы объявить те в супертипе (Message в этом примере) и иметь возможность писать функции, которые работают с супертипом, если им нужен доступ к этим общим полям (messageId в этом примере).
fun operate(m: Message) {
use(m.messageId)
}
Я попытался выполнить это, расширив классы данных из закрытого класса.
Классы данных могут распространять закрытые классы, но не я не уверен, как/если они могут принимать аргументы, требуемые закрытым классом супертипа.
-
Расширение обычного класса из закрытого класса компилируется просто отлично.
sealed class Message(val messageId: String) class Track(val event: String, messageId: String): Message(messageId)
-
Однако его изменение в класс данных не компилируется ( "Основной конструктор класса данных должен иметь только параметры свойства (val/var)".).
sealed class Message(val messageId: String) data class Track(val event: String, messageId: String): Message(messageId)
-
Объявление параметра как свойства также не компилируется ("'messageId' скрывает член супертипа 'Message' и нуждается в переопределении 'модификатора').
sealed class Message(val messageId: String) data class Track(val event: String, val messageId: String): Message(messageId)
-
Открытие свойства супертипа и его переопределение в каждом из базовых классов компилируется отлично:
sealed class Message(open val messageId: String) data class Track(val event: String, override val messageId: String): Message(messageId)
В идеале я хотел бы что-то близкое к Варианту 2 - он позволяет мне комбинировать лучшее из обоих миров.
В противном случае мне кажется, что мои параметры - либо переносить мои собственные функции класса данных (copy, hashcode, equals и т.д.) с помощью опции 1, либо жить с компромиссом, открыв свойства супертипа с опцией 4.