Данные и открытая несовместимость, какая у меня альтернатива?
Я делаю Kotlin порт гли, и я застрял сейчас
На самом деле у меня есть следующее
open class Texture
расширен несколькими классами, такими как Texture2d
Сейчас, Texture
имеет довольно некоторые свойства
protected val storage: StorageLinear?
protected val target: Target
protected val format: Format
protected val baseLayer: Int
protected val maxLayer: Int
protected val baseFace: Int
protected val maxFace: Int
protected val baseLevel: Int
protected val maxLevel: Int
protected val swizzles: Swizzles
поэтому я хотел бы иметь его как data
класс для того, чтобы использовать equals()
что идет с этим..
но, к сожалению data
а также open
несовместимы.. (см. этот вопрос)
Один способ, которым я могу решить это, я мог бы написать свой собственный equals()
метод, но это будет шаблонный код и грязный, именно две из основных причин, почему я перешел на kotlin через Java
Другой способ, так как все class
расширяется Texture
на самом деле ничего не добавить, они действуют как строители (выглядит CPP Texture2d
класс), будет ли это использование их в качестве... строителей (см. этот отличный ответ от Кирилла)
Но так как ничего не приходит бесплатно, большой недостаток этого решения состоит в том, что я потерял бы возможность иметь Texture2d
как класс и Texture2d
имеет хороший оператор[]
чтобы получить отдельные изображения текстур..
Поскольку сообщество kotlin выглядит чрезвычайно активным и поддерживающим, я хотел бы знать, если у вас есть идея получше...
2 ответа
ИМХО наиболее практичным решением будет генерировать equals
в Texture
и покончим с этим.
Классы данных имеют очень узкое применение специально. Ваш пример не совсем соответствует классическому data
класс, вот почему у вас есть эта проблема.
Использование интерфейсов и шаблона делегирования:
interface Texture {
fun method1()
fun method2()
}
data class TextureImpl(val baseLayer: Int, val maxLayer: Int): Texture{
override fun method1() {
}
override fun method2() {
}
}
data class Texture2d(val impl: TextureImpl) : Texture by impl
data class Texture3d(val impl: TextureImpl) : Texture by impl
Вы инициализируете конкретные классы как Texture2d
с TextureImpl
который обычно был бы абстрактным, но мы не можем сделать класс данных абстрактным.
Надеюсь, я не ошибусь, если скажу, что заменил наследство здесь композицией.
Имеет ли это смысл в вашем случае?