y
11/17/2022, 7:17 AMsealed class where children share some common variables. how do I do this with the least amount of boilerplate?
what I was recommended is something like
sealed class Parent {
abstract val s: String
data class Derived1(override val s: String, ...) : Parent()
data class Derived2(override val s: String, ...) : Parent()
sealed class Derived3() : Parent() {
data class Derived4(override val s: String, ...) : Derived3()
}
}
which repeats the val s declarationgildor
11/17/2022, 7:21 AMy
11/17/2022, 7:22 AMephemient
11/17/2022, 7:26 AMsealed class Parent(val s: String) {
class Derived1(s: String) : Parent(s)
but it means something a bit differenty
11/17/2022, 7:26 AMParent class, right?gildor
11/17/2022, 7:30 AMy
11/17/2022, 7:32 AMs, right?y
11/17/2022, 7:32 AMephemient
11/17/2022, 7:36 AMsealed class Parent(open val s: String) {
class Derived(override val s: String) : Parent(s)
then you could potentially have a `data class`… but I would not recommend it. it's confusing and does lead to multiple fields internally shadowingephemient
11/17/2022, 7:36 AMdata class then stick with what you wrote originallyy
11/17/2022, 7:37 AMdata class , the minimum boilerplate version would be the above version? (open val which is then passed to the Parent constructor)ephemient
11/17/2022, 7:37 AMopen val versionephemient
11/17/2022, 7:38 AMval passed to the Parent constructor is the least boilerplate version if you only have normal class and object, yesy
11/17/2022, 7:40 AMdata class, right?
sorry for asking again, this is just somewhat confusing.ephemient
11/17/2022, 7:41 AMsealed out of the discussion for a moment,
open class Parent(val s: String)
class Derived(s: String) : Parent(s)
what makes you think there's any shadowing?y
11/17/2022, 7:43 AMabstract + re-declarations is the right way, because otherwise shadowing might happen. I realize now that it’s a data class thing. there’s actually no need for the sugar introduced by data in my current use caseephemient
11/17/2022, 7:44 AMdata class (or any other time you want to have a concrete val in the child) you should prefer an abstract val over a concrete open val in the parenty
11/17/2022, 7:44 AMephemient
11/17/2022, 7:49 AMopen class Parent(open val s: String)
class Derived(override val s: String) : Parent(s)
it's equivalent to the following Java
public class Parent {
private final String s;
public Parent(String s) {
this.s = s;
}
public String getS() {
return this.s;
}
}
public final class Derived {
private final String s;
public Derived(String s) {
super(s);
this.s = s;
}
@Override
public String getS() {
return this.s;
}
}
where you have two getters and two fields. the getters aren't problematic because virtual dispatch will always pick the more specific one, but the fields Parent.s and Derived.s are definitely both present in an object of type Derivedy
11/17/2022, 8:05 AMStephan Schröder
11/17/2022, 8:56 AMephemient
11/17/2022, 10:26 AMsealed interface { val s } is the same as sealed class { abstract val s }, as far as how the property is inheritedStephan Schröder
11/17/2022, 11:42 AMephemient
11/17/2022, 11:53 AMephemient
11/17/2022, 11:54 AMephemient
11/17/2022, 11:54 AMephemient
11/17/2022, 11:55 AMStephan Schröder
11/17/2022, 11:58 AM