Intereting Posts
Использование JPA + H2 с Spring Boot + Kotlin – Загрузка с ошибкой Надежное измерение распределения JVM ControlsFX SpreadsheetView rowspan IndexOutOfBoundsException Как получить результат функции огурца «Ошибка: не удалось найти или загрузить основной« ИЛИ »класс не найден» – с помощью андроидного модуля (Gradle / IntelliJ) Создайте новый список из двух других списков разных типов, сравнивая значения каждого типа Передача массива Parcelable с использованием Intent.putExtra Весенние данные mongodb и kotlin Kotlin gradle.build ZipException из-за дубликатов класс данных kotlin + проверка бонуса jsr 303 Как отклонить диалоговое окно предупреждения Android через setOnEditorActionListener? Как отключить кнопку точки в android Kotlin Почему var с частным сеттером является инвариантной позицией? Скрипт Kotlin как параметры конфигурации Gradle, не использующие расширение KotterKnife – не может использовать bindView (R.id.example_id) для некоторых классов

Kotlin и generics, реализующие абстрактный общий класс с общим массивом

У меня есть следующий абстрактный класс

abstract class Vec2t<T : Number>(open var x: T, open var y: T)

осуществляется

data class Vec2(override var x: Float, override var y: Float) : Vec2t<Float>(x, y)

Пока все работает отлично

Теперь, я хотел бы сделать что-то подобное для матриц, это в настоящий момент мой абстрактный класс

abstract class Mat2t<T : Number>(open var value: Array<out Vec2t<T>>)

которые должны быть реализованы

class Mat2(override var value: Array<Vec2>) : Mat2t<Float>(value)

Но компилятор жалуется на Array<Vec2> :

Ошибка: (8, 32) Kotlin: Тип 'value' не соответствует типу переопределенного var-property 'public open var value: Array>, определенного в main.mat.Mat2t'

Мне сказали:

  • Я не могу изменить тип свойства var когда я его переопределяю (но на самом деле я его не меняю, я переопределяю его подтипом .. это то же самое?)
  • mat2.value = object : Vec2t<Float>() { ... } недействителен, что не должно иметь место для любого подкласса Mat2t<Float>

Как я могу преодолеть эти проблемы?

Есть ли способ иметь абстрактный общий класс Mat2t с общим массивом и реализовать его с помощью массива подтипов?

    Вы можете сделать это, сделав свой общий параметр подтипом Vec2t вместо подтипа типа универсального параметра Vec2t ( T : Number ):

     abstract class Mat2t<T : Vec2t<*>>(open var value: List<T>) class Mat2(override var value: List<Vec2>) : Mat2t<Vec2>(value) 

    Обратите внимание, что поскольку вы переопределяете var value вам не нужно иметь его в конструкторе абстрактного класса. То же самое касается Vec2t . например:

     abstract class Vec2t<T : Number> { abstract var x: T abstract var y: T } class Vec2(override var x: Float, override var y: Float) : Vec2t<Float>() abstract class Mat2t<T : Vec2t<*>> { abstract var value: List<T> } class Mat2(override var value: List<Vec2>) : Mat2t<Vec2>() 

    Тогда эти абстрактные классы могут быть даже представлены как интерфейсы, если это вам подходит:

     interface Vec2t<T : Number> { var x: T var y: T } data class Vec2(override var x: Float, override var y: Float) : Vec2t<Float> interface Mat2t<T : Vec2t<*>> { var value: List<T> } data class Mat2(override var value: List<Vec2>) : Mat2t<Vec2>