https://kotlinlang.org logo
#getting-started
Title
# getting-started
m

Michael Langford

10/19/2021, 9:30 PM
Data modeling question: I'm trying to essentially model 5 different csv files that have a few common fields as Kotlin objects that are going to be displayed and edited in lists. So like page 1 would be identifier, time, last_update, location name, color. Page 2 would be identifier, time, last_update, activity_type, length, etc, with all of them having identifier, time, and last_update in common. In my Android app's UI, these will all be displayed in a list, by time. Is there a gotcha that makes sealed classes a bad move for this data modeling situation?
d

Damian Zawadzki

10/19/2021, 10:38 PM
Its sound like it fits good
Copy code
sealed class Page {
    abstract val identifier: UUID
    abstract val time: LocalDateTime
    abstract val lastUpdate: LocalDateTime?

    data class Page1OrSomething(
        val locationName: String, val color: Int,
        override val identifier: UUID,
        override val time: LocalDateTime,
        override val lastUpdate: LocalDateTime?,
    ) : Page()

    data class Page2OrSomething(
        val activityType: String, val length: Int,
        override val identifier: UUID,
        override val time: LocalDateTime,
        override val lastUpdate: LocalDateTime?,
    ) : Page()
}
m

Michael Langford

10/20/2021, 4:21 PM
Thanks a lot. This is the first big app I'm doing in Kotlin (my previous android work was java), and wanted to make sure I wasn't shooting myself in the foot with something like JSON encoding or display time performance
One follow up question on this track: I see that "page 10" has inserted some analytics inline as fake events. I'd like to model those as their own class. I figured out the syntax of nesting sealed classes, but, it appears I have the choice or not to have "abstract override val identifier" etc on the nested class. This feels...weird. Syntactically, what's going on there? I'm surprised I'm not getting a warning it's superfluous or something if it truly doesn't matter.
Copy code
sealed class Page {
        abstract val identifier: UUID
        abstract val time: LocalDateTime
        abstract val lastUpdate: LocalDateTime

        sealed class Page1OrSomethingI: Page() {
                abstract override val identifier: UUID
                abstract override val time: LocalDateTime
                abstract override val lastUpdate: LocalDateTime

                data class Page10RealBrSomething(
                        val activityType: String, val length: Int,
                        override val identifier: UUID,
                        override val time: LocalDateTime,
                        override val lastUpdate: LocalDateTime,
                ): Page1OrSomethingI()
                data class Page10AnalyticsJammedInTable(
                        override val identifier: UUID,
                        override val time: LocalDateTime,
                        override val lastUpdate: LocalDateTime,
                ) : Page1OrSomethingI()
        }


        data class Page2OrSomething(
                val activityType: String, val length: Int,
                override val identifier: UUID,
                override val time: LocalDateTime,
                override val lastUpdate: LocalDateTime,
        ) : Page()
}

///  This also compiles, without apparent warnings

sealed class Page {
        abstract val identifier: UUID
        abstract val time: LocalDateTime
        abstract val lastUpdate: LocalDateTime

        sealed class Page1OrSomethingI: Page() {
//                abstract override val identifier: UUID
//                abstract override val time: LocalDateTime
//                abstract override val lastUpdate: LocalDateTime

                data class Page10RealBrSomething(
                        val activityType: String, val length: Int,
                        override val identifier: UUID,
                        override val time: LocalDateTime,
                        override val lastUpdate: LocalDateTime,
                ): Page1OrSomethingI()
                data class Page10AnalyticsJammedInTable(
                        override val identifier: UUID,
                        override val time: LocalDateTime,
                        override val lastUpdate: LocalDateTime,
                ) : Page1OrSomethingI()
        }


        data class Page2OrSomething(
                val activityType: String, val length: Int,
                override val identifier: UUID,
                override val time: LocalDateTime,
                override val lastUpdate: LocalDateTime,
        ) : Page()
}
Its really weird both versions compile without warnings
d

Damian Zawadzki

10/20/2021, 5:53 PM
Copy code
ealed class Page1OrSomethingI: Page() {
//                abstract override val identifier: UUID
//                abstract override val time: LocalDateTime
//                abstract override val lastUpdate: LocalDateTime

                data class Page10RealBrSomething(
                        val activityType: String, val length: Int,
                        override val identifier: UUID,
                        override val time: LocalDateTime,
                        override val lastUpdate: LocalDateTime,
                ): Page1OrSomethingI()
Because you are actuallly implementing those commented properties in Page10RealBrSomething and Page1OrSomething. Sealed class is like abstract class so you don't need too implement anything. Also sealed class cannot be directly instantiated.
🙌 1
3 Views