Расширить класс данных в Котлине
классы данных, похоже, являются заменой старомодным POJOs в Java. Вполне ожидаемо, что эти классы позволят наследование, но я не вижу удобного способа расширить класс данных. Мне нужно что-то вроде этого:
open data class Resource (var id: Long = 0, var location: String = "")
data class Book (var isbn: String) : Resource()
код выше терпит неудачу из-за столкновения component1()
методы. Уезжаю data
аннотации только в одном из классов не работают тоже.
возможно, есть еще одна идиома для расширения данных занятия?
UPD: я мог бы аннотировать только дочерний класс ребенка, но data
аннотации обрабатывает только свойства, объявленные в конструкторе. То есть, я должен был бы объявить все родительские свойства open
и переопределить их, что это некрасиво:
open class Resource (open var id: Long = 0, open var location: String = "")
data class Book (
override var id: Long = 0,
override var location: String = "",
var isbn: String
) : Resource()
4 ответа:
правда в том, что классы данных не слишком хорошо играют с наследованием. Мы рассматриваем возможность запрета или строгого ограничения наследования классов данных. Например, известно, что нет способа реализовать
equals()
правильно в иерархии на неабстрактных классах.Итак, все, что я могу предложить: не используйте наследование с классами данных.
объявить свойства в суперклассе вне конструктора как абстрактные и переопределить их в подклассе.
abstract class Resource { abstract var id: Long abstract var location: String } data class Book ( override var id: Long = 0, override var location: String = "", var isbn: String ) : Resource()
выше решение с использованием абстрактного класса фактически генерирует соответствующий класс и пусть класс данных простирается от него.
Если вы не предпочитаете абстрактный класс, как об использовании интерфейс?
интерфейс в Котлине может иметь свойства как показано в этой в этой статье..
interface History { val date: LocalDateTime val name: String val value: Int } data class FixedHistory(override val date: LocalDateTime, override val name: String, override val value: Int, val fixedEvent: String) : History
мне было любопытно, как Котлин скомпилировать это. Вот эквивалентный код Java (генерируется с использованием байт-кода Intellij [Kotlin] особенность):
public interface History { @NotNull LocalDateTime getDate(); @NotNull String getName(); int getValue(); } public final class FixedHistory implements History { @NotNull private final LocalDateTime date; @NotNull private final String name; private int value; @NotNull private final String fixedEvent; // Boring getters/setters as usual.. // copy(), toString(), equals(), hashCode(), ... }
Как вы можете видеть, это работает точно так же, как обычный класс данных!