Ошибка или особенность: Kotlin позволяет изменить «val» на «var» в наследовании

Каждому языку необходимо определить, что является допустимым символом для идентификатора, а что нет. Частью рассмотрения будет простота разбора, часть должна состоять в том, чтобы избежать двусмысленности (другими словами, даже идеальный алгоритм синтаксического анализа не мог быть уверенным все время), часть будет предпочтительнее языкового дизайна (в случае с аналогией Java с C, C ++), а некоторые просто будут произвольными.

Точка в том, что это должно быть что-то, поэтому это то, что есть.

17
задан miho 2 April 2014 в 18:54
поделиться

1 ответ

Я бы посчитал это особенностью, так как изменение val на var накладывает более слабые ограничения на использование и не может нарушить код суперкласса . Аналогичная ситуация может наблюдаться с модификаторами видимости:

trait A {
  protected fun print() {
    ...
  }
}

class AImpl: A {
  public override fun print() {
    ...
  }
}

В этом примере ограничения видимости также смягчаются подклассом, хотя некоторые люди рассматривают эту технику как антипаттерн.

Как защитить значения от изменения наследованием?

В kotlin вы можете явно определить, может ли какой-либо конкретный член класса быть переопределен подклассом с помощью модификатора open. Однако в чертах все члены открыты по умолчанию. Решение состоит в том, чтобы заменить признак классом, чтобы вы могли контролировать наследование:

abstract class A {
  fun print() {
    ...
  }

  val x : Int = 2;
}

class AImpl(x : Int) : A() {
  override var x = x // compilation error
}
3
ответ дан Jk1 2 April 2014 в 18:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: