-1

open class OpenBase(open val value: Int)

interface AnotherExample {
    val anotherValue: OpenBase
}

open class OpenChild(value: Int) : OpenBase(value), AnotherExample {
    override var value: Int = 1000
        get() = field - 7
    override val anotherValue: OpenBase = OpenBase(value)
}

open class AnotherChild(value: Int) : OpenChild(value) {
    final override var value: Int = value
        get() = field
        set(value) { field = value * 2 }
    final override val anotherValue: OpenChild = OpenChild(value)
}

fun main() {
    val openChild = OpenChild(42)
    println("OpenChild value: ${openChild.value}")
    println("OpenChild anotherValue: ${openChild.anotherValue.value}")

    val anotherChild = AnotherChild(42)
    println("AnotherChild value: ${anotherChild.value}")
    println("AnotherChild anotherValue: ${anotherChild.anotherValue.value}")
    
    anotherChild.value=69 //HERE
    println("AnotherChild value: ${anotherChild.value}")
    println("AnotherChild anotherValue: ${anotherChild.anotherValue.value}")
}


I was learning kotlin OOPS and was playing with an example; I was expecting an error but got no error. Why am I able to modify the value mentioned final?

cheems
  • 164
  • 7
  • 2
    You're confusing final and val. Final doesn't mean the variable is const in Kotlin. – Zoe Jul 17 '23 at 07:01
  • `val` doesn't mean final, const or immutable - it means read-only. It can change, but you can't mutate it directly. – broot Jul 17 '23 at 08:06

1 Answers1

1

The final in final override var value only means that the property can't be overridden in other subclasses. If want value to be read only in AnotherChild, you must declare it as val instead of var. Or, if you do need a private setter, declare it as var but add private to set.

In the context of class members, val simply means "property with a getter", and var means "property with a getter and a setter. The latter is a valid override for the former, which is what you are doing in AnotherChild`.

Jorn
  • 20,612
  • 18
  • 79
  • 126