Доступ к свойствам подкласса объявленного типа объекта - PullRequest
0 голосов
/ 11 октября 2018

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

abstract class AbstractBook {
    abstract val type: String
    abstract val privateData: Any
    abstract val publicData: Any
}

и следующий класс, который наследует класс AbstactBook:

data class FantasyBook (
    override val type: String = "FANTASY",
    override val privateData: FantasyBookPrivateData,
    override val publicData: FantasyBookPublicData
) : AbstractBook()

А затем есть этот класс, который должен включать данные из любоготип AbstractBook:

data class BookState(
        val owner: String,
        val bookData: AbstractBook,
        val status: String
)

Если у меня есть экземпляр BookState, как мне проверить, какой это type объекта Book, и затем получить доступ к соответствующим переменным FantasyBookPrivateData и FantasyBookPublicData?

Надеюсь, я хорошо описал свою проблему и заранее благодарю за любую помощь!

Ответы [ 2 ]

0 голосов
/ 11 октября 2018

То, что вы описываете, это sealed class:

sealed class Book<T, K> {

    abstract val type: String
    abstract val privateData: T
    abstract val publicData: K

    data class FantasyBook(
            override val type: String = "FANTASY",
            override val privateData: String,
            override val publicData: Int) : Book<String, Int>()
}

, и в вашем data class вы можете выполнить сопоставление с шаблоном следующим образом:

data class BookState(
        val owner: String,
        val bookData: Book<out Any, out Any>,
        val status: String) {

    init {
        when(bookData) {
            is Book.FantasyBook -> {
                val privateData: String = bookData.privateData
            }
        }
    }
}

для доступа к вашим данным втипобезопасный способ.Это решение также делает type избыточным, поскольку у вас есть эта информация в самом классе.

Я согласен с @Marko Topolnik, что это похоже на запах кода, поэтому вы можете переосмыслить свой дизайн.

0 голосов
/ 11 октября 2018
interface AbstractBook<T , U> {
    val privateData: T
    val publicData: U
}

data class FantasyBook (
    override val privateData: FantasyBookPrivateData,
    override val publicData: FantasyBookPublicData
) : AbstractBook<FantasyBookPrivateData , FantasyBookPublicData>

data class BookState(
    val owner: String,
    val bookData: AbstractBook<*, *>,
    val status: String
)

if(bookState.bookData is FantasyBook) {
    // Do stuff
}

Создание переменной типа - это слабый стиль написания на языке типов.Вы должны использовать универсальный класс.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...