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

Я делаю порт kotlin для gli и теперь я застрял

На самом деле у меня есть следующее

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.

С другой стороны, поскольку все classes, расширяющие Texture, на самом деле ничего не добавляют, они действуют как строители (выглядит cpp Texture2d class), будет ли это использование их в качестве... строителей (см. отличный ответ от Кирилла)

Но поскольку ничего не дается бесплатно, большим недостатком этого решения является то, что я потеряю возможность иметь Texture2d в качестве класса, а Texture2d имеет хороший оператор [] для извлечения отдельных изображений текстур.

Поскольку сообщество kotlin выглядит чрезвычайно активным и поддерживающим, я хотел бы знать, есть ли у вас идеи получше.


person elect    schedule 30.10.2016    source источник


Ответы (2)


ИМХО, наиболее практичным решением было бы сгенерировать equals в Texture и покончить с этим.

Классы данных специально имеют очень узкое применение. Ваш пример не очень подходит для классического класса data, поэтому у вас есть эта проблема.

person voddan    schedule 31.10.2016
comment
Вау, я не ожидал, что этот ответ будет отмечен )) Ведь @elect, ты знал это с самого начала - person voddan; 31.10.2016
comment
Ну, вы в принципе подтвердили мой временный выбор, так что это своего рода ответ для меня :p - person elect; 01.11.2016

Использование интерфейсов и шаблона делегирования:

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

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

Есть ли смысл в вашем случае?

person klimat    schedule 30.10.2016
comment
Я пока выбираю вариант equals(), но ваше предложение интересно, я подумаю над ним, +1 - person elect; 31.10.2016