David Kubecka
12/17/2023, 10:16 AMinterface Health {
var health: Int
val isDead: Boolean get() = health <= 0
fun damage(amount: Int) {
health -= amount
}
}
It has the clear drawback that health
can be mutated directly. I wondered whether it couldn't be fixed somehow, e.g. something like
interface Health {
protected var healthInt: Int
val health: Int get() = healthInt
val isDead: Boolean get() = health <= 0
fun damage(amount: Int) {
healthInt -= amount
}
}
For some reason which I don't yet understand, protected
is not allowed in interfaces.
Is there possible a different strategy how to keep the default implementations while hiding the direct health
setter?Sam
12/17/2023, 10:26 AMSam
12/17/2023, 10:27 AMDavid Kubecka
12/17/2023, 10:35 AMclass HealthImpl(initialHealth: Int): Health {
override var health: Int = initialHealth
private set
override val isDead: Boolean get() = health <= 0
override fun damage(amount: Int) {
health -= amount
}
}
is that once I have an instance of Health
, e.g.
val orc = Orc.new(position = 5.0 to 0.0, damage = 30)
then orc.health
is val but it can be changed, possibly in a different thread. Perhaps I'm just misunderstanding the message that val communicates. When I see a val in the code I would like to think immutable but that clearly isn't the case here.Sam
12/17/2023, 10:40 AMprivate set
part ensures that it can only be modified by methods inside HealthImpl
👍Sam
12/17/2023, 10:43 AMval
can rarely really be relied on to mean "immutable", so it can definitely be misleading. The HealthImpl
could just as easily expose a way for anyone and everyone to mutate the underlying value, if it wanted to.David Kubecka
12/17/2023, 10:43 AMHealthImpl
could just as easily expose a way for anyone and everyone to mutate the underlying value, if it wanted to
Yeah, so why not to use the default interface implementation with the public setter, then?David Kubecka
12/17/2023, 10:45 AMorc.health
is val while it actually can be mutated (even if not by ourselves)?Sam
12/17/2023, 10:50 AMval
properties are for. They're not supposed to be immutable.Sam
12/17/2023, 10:52 AMval
properties in data classes (or more specifically, final properties defined without a setter and within the current module) are a special case, where the compiler will guarantee they don't change, which does make things more confusing 😞Sam
12/17/2023, 10:52 AMval
can change whenever it wants and nobody should be surprised by thatSam
12/17/2023, 10:54 AMDavid Kubecka
12/17/2023, 10:57 AMval=immutable
. But I'm not yet using the delegation model so it's good to know that once I start I should change my thinking paradigm.David Kubecka
12/17/2023, 10:58 AMMaybe it would be useful to have a new modifier that makes a val immutable thoughMost probably yes because AFAIK there's no general way how to declare a property really immutable...
Sam
12/17/2023, 10:58 AMval
being read-only but not immutable are Collection.size
and String.length
. They demonstrate the usefulness pretty well.Sam
12/17/2023, 10:59 AMDavid Kubecka
12/17/2023, 11:02 AMCollection.isEmpty
: for some reason I would rather like to have this as method. Perhaps I tend to view these boolean methods/props on a different complexity level than the other props like size etc. But that's only my gut feeling 🙂Sam
12/17/2023, 11:03 AMSam
12/17/2023, 11:06 AMArjan van Wieringen
12/17/2023, 8:21 PM