Eryk Lepszy
01/26/2023, 2:36 PMsealed class SomeSealed(open val text: String)
data class SomeImplementation(override val text: String) : SomeSealed(text)
the field text
is not actually overridden, but just hidden by the new declaration?Sam
01/26/2023, 2:43 PMopen
properties and functions still exist even after they’ve been overridden. For example, a subclass can call its superclass’s functions and property accessors using the super
keyword: https://kotlinlang.org/docs/inheritance.html#calling-the-superclass-implementationephemient
01/26/2023, 5:40 PMsealed class SomeSealed {
abstract val text: String
}
data class SomeImplementation(override val text: String) : SomeSealed()
then there is only one implementation of text
Eryk Lepszy
01/26/2023, 6:11 PMsealed class SomeSealed(open val text: String) {
protected val initialized = text.drop(1)
}
data class SomeImplementation(override val text: String) : SomeSealed(text) {
val derivedText = initialized.drop(1)
}
But I still needed SomeImplementation
to be a data class and I wanted to keep only one text field. Doing something like that with the abstract val
approach unfortunately wouldn't initialize everything in the right order. Eventually I changed to the abstract val
variant and duplicated the initialized field in subclasses, as it was the easiest solution.Stephan Schröder
01/27/2023, 8:08 AMoverride val
in SomeImplementation
in the first place? I'd just drop that and let text
be a parameter there.
sealed class SomeSealed(val text: String) {
protected val initialized = text.drop(1)
}
data class SomeImplementation(text: String) : SomeSealed(text) {
val derivedText = initialized.drop(1)
}
Eryk Lepszy
01/27/2023, 10:12 AMStephan Schröder
01/30/2023, 9:15 AMdata
.
Alternatively you could improve on @ephemient’s suggestion by using getters or lazy properties:
sealed class SomeSealed {
abstract val text: String
protected val initialized: String
get() = this.text.drop(1)
}
data class SomeImplementation(override val text: String) : SomeSealed() {
val derivedText: String
get() = initialized.drop(1)
}
or if you don't want to compute the value every single time by lazy
should work
sealed class SomeSealed {
abstract val text: String
protected val initialized: String by lazy {
this.text.drop(1)
}
}
data class SomeImplementation(override val text: String) : SomeSealed() {
val derivedText: String by lazy {
this.initialized.drop(1)
}
}
But actually first you should make sure that ephemient's solution doesn't work. Now that I think of it, it actually might, even with your additions. Since SomeSealed is abstract, the text-field will (should 🤔) exists when the initialization is executed
sealed class SomeSealed {
abstract val text: String
protected val initialized: String = this.text.drop(1)
}
data class SomeImplementation(override val text: String) : SomeSealed() {
val derivedText: String = this.initialized.drop(1)
}
Eryk Lepszy
01/30/2023, 11:16 AMdata
In case of your last example that won't work, because the base class initialization is done first:
https://kotlinlang.org/docs/inheritance.html#derived-class-initialization-order
I really like the lazy
example though, I didn't think of using it there. I'm not completely sure if it will fit my exact use-case, but that looks like a better solution for what I was looking for. Thank you!Stephan Schröder
02/02/2023, 5:46 PMlazy
it is 🤷♂️