Home > Blockchain >  Why immutability of super class is not forced in child class?
Why immutability of super class is not forced in child class?

Time:02-11

You can break immutabiliy of super class, even if you declare the immutable fields with val in interface or abstract class.

interface Foo {
    val bar: String // immutable
}

class FooImpl : Foo {
    override var bar: String = "bar" // mutable

    init {
        bar = "changed"
    }
}

println(FooImpl().bar) // changed

I expected above code will occurs compile error, but it works. Why is this possible in kotlin?

CodePudding user response:

val doesn’t mean immutable. It means read-only. Even if you don’t override it as a var you could make it a val that returns a different value each time.

So expanding it to also be writable isn’t breaking any contract.

There is no way to enforce an open property to be immutable. Best you can do is use documentation that declares that it will not behave correctly if it doesn’t return the same value every time.

CodePudding user response:

From the language spec:

A property declaration D which overrides property declaration B should satisfy the following conditions.

  • Mutability of D is not stronger than mutability of B (where read-only val is stronger than mutable var);
  • Type of D is a subtype of type of B ; except for the case when both D and B are mutable (var), then types of D and B must be equivalent.

So your overriding property can add mutability, and also use a more specific subtype (e.g. Int instead of Number) so long as the declaration isn't a var (so you can't write a Double to it via the interface).

One way you could look at it, is your original val is sort of declaring a getBar(): String function which you're overriding. By making it a var, you're also defining a setString(string) function in your own class.

If you try to access your object as Foo then that setter doesn't exist, because it's not (implicitly) defined in the interface. It's a separate function on your class, just conveniently expressed by tweaking the property definition (in a defined, restricted way)

  • Related