why can a `val` from an interface be overwritten a...
# announcements
t
why can a
val
from an interface be overwritten as
var
in the implementation?
b
You can also override a val property with a var property, but not vice versa. This is allowed because a val property essentially declares a getter method, and overriding it as a var additionally declares a setter method in the derived class.
m
From point of anyone using the interface, that's a
val
t
but OTOH one could argue that the
set
of the
val
is private and declaring it
var
in the implementation grants access that shouldn't be allowed...
yeah indeed it looks like a
val
and then it changes...
a
you can change private to public in a child class
t
you cannot even access it from a child class
m
val
properties are read-only, not immutable
t
yeah that;s a good point indeed
m
Copy code
val counter: Int
    get() = _counter++
or
Copy code
val isEmpty: Boolean
    get() = this.size == 0
t
yeah, point taken, thank you 🙂
n
It all depends how you look at it but it is a bit odd. It basically implies the underlying data is protected, conceptually
In Java iirc more typical is that the data is private and then you implement a public getter, in this case a derived class cannot add a setter
g
derived class cannot add a setter
same in Kotlin, you just override gettere and setters, underlying backing field is just implementation detail
n
If the base class has a val, you can override with var. This is the same as adding a setter.
That's how the discussion started 🙂
The point is just that if you are trying to understand properties by analogy of "private data + public getter (and maybe setter)", which is how Kotlin itself tries to describe it
then this particular model breaks down when you consider inheritance
g
Interface cannot have any state (and data), it's just a contract, so I it's not different from Java
n
Overriding properties is not limited to interfaces
It works with classes too
Copy code
open class Foo {
    open val x: Int get() { ... }
}

class Bar1 : Foo() {
    override val x: Int = ...
}
Example from kotlin docs
No matter how you slice it you can't change the fact that Kotlin is granting access to the "underlying" data to derived classes (but not outside the class)
Basically, it means that the closest java analogy to Kotlin properties is protected data, with public (or whatever) getter and setter functions
g
Sure, it works with classes, same way in Java. It doesn't give access to underlying data outside of available API