По предложению @jsuereth я создал расширение, отмеченное галочкой для Scala, просто для протокола, которое, я надеюсь, правильно подытоживает содержание обсуждений здесь. Спасибо за ваш вклад! Билет можно найти здесь, содержание ниже: https://issues.scala -lang.org / browse / SI-4762
Непреднамеренное затенение полей базового класса в производных классах, желательно предупреждение
Проблема возникает, когда (a) параметр класса в производном классе использует тот же
символ как поле или функция в базовом классе и (б) этот символ базового класса
впоследствии доступен в производном классе. Параметр производного класса
заставляет компилятор автоматически генерировать поле с тем же именем, что и тени
символ базового класса. Любая ссылка на этот символ в производном классе,
предназначен для ссылки на поле базового класса, то непреднамеренно (а) вызывает
дублирующее определение поля и (б) неожиданно (но правильно) относится
к автоматически сгенерированному полю в производном классе.
Пример кода:
class Base( val x : String )
class Derived( x : String ) extends Base( x ) { override def toString = x }
Поскольку базовый класс имеет значение val для генерации поля и производного класса
нет, разработчик явно намерен использовать «Производные» «х» только для
сквозной к Base, и поэтому ожидает ссылку в 'toString' на
дать базовое значение. Вместо этого ссылка в 'toString' вызывает компилятор
автоматически генерировать поле Derived.x, которое скрывает поле Base.x,
что привело к ошибке. Компилятор ведет себя правильно, но в результате
ошибка программирования.
Сценарий использования (с полями var для более наглядной иллюстрации рисков):
class Base( var x : Int ) { def increment() { x = x + 1 } }
class Derived( x : Int ) extends Base( x ) { override def toString = x.toString }
val derived = new Derived( 1 )
println( derived.toString ) // yields '1', as expected
derived.increment()
println( derived.toString ) // still '1', probably unexpected
Поскольку эта проблема возникает всякий раз, когда кто-либо использует способ инициализации по умолчанию
Поля базового класса из производного класса в Scala, сценарий
быть чрезвычайно распространенным явлением и приводить к множеству ошибок программирования (легко исправляемых,
но все же) для новых пользователей.
Существует легкое решение этой проблемы (используйте разные имена для производных
Параметр класса, например, _x, theX, initialX и т. д.), но это вводит
ненужные лишние символы.
Решение A (минимальное): выдает предупреждение всякий раз, когда компилятор делает вывод, что
Параметр класса требует автоматически сгенерированного поля в производном классе, который
затеняет символ, уже определенный в базовом классе.
Решение B: Обход, все еще необходимый для решения A, должен прийти
с новым именем символа каждый раз, когда инициализируется поле базового класса. это
сценарий возникает все время и загрязнение пространства имен с обходным путем
Имена полей, такие как _x и theX, кажутся нежелательными. Вместо этого это может быть хорошо
иметь способ подавить автоматическую генерацию поля, если разработчик
определяет, что символы производного класса в противном случае будут скрывать базу
символ класса (например, после предупреждения решения A). Может быть полезным
дополнение к Scala будет модификатор типа «noval» (или «passthrough» или
'temp' или что-то еще - в дополнение к 'val' и 'var'), например:
class Base( var x : Int ) { def increment() { x = x + 1 } }
class Derived( noval x : Int ) extends Base( x ) { override def toString = x.toString }
val derived = new Derived( 1 )
println( derived.toString ) // yields '1', as expected
derived.increment()
println( derived.toString ) // still '2', as expected