Данные и открытая несовместимость, какая у меня альтернатива?

Я делаю 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 который обычно был бы абстрактным, но мы не можем сделать класс данных абстрактным.

Надеюсь, я не ошибусь, если скажу, что заменил наследство здесь композицией.

Имеет ли это смысл в вашем случае?

Другие вопросы по тегам