Я только начал изучать язык Kotlin. Я борюсь с наследованием, var&val и побочными эффектами.
Если я объявлю трейт A
с val x
и переопределю x
в AImpl
, его можно переопределить как var
(см. код ниже). Удивительно, но на метод print()
в A
влияет переназначение x
, хотя x
является значением в A
. Это баг или фича?
Код:
trait A {
fun print() {
println("A.x = $x")
}
val x : Int;
}
class AImpl(x : Int) : A {
override var x = x; // seems like x can be overriden as `var`
}
fun main(args: Array<String>) {
val a = AImpl(2)
a.print() // A.x = 2
a.x = 3; // x can be changed
// even though print() is defined in trait A
// where x is val it prints x = 3
a.print() // A.x = 3
}
Я осознаю тот факт, что если я определяю a
с типом A
явно, мне не разрешается изменять x
:
val a = AImpl(2) : A
a.x = 3 // ERROR: value x cannot be reassigned
Но, как показывает первый случай, наследование может вызывать побочные эффекты, явно не предназначенные для A
. Как защитить значения от изменения по наследству?