Отличия при переопределении унаследованных полей конструктора? - PullRequest
7 голосов
/ 12 июля 2011

Рассмотрим этот простой класс Scala:

class A(val d: Int)

Есть ли разница в Scala (в поведении или сгенерированном байт-коде) между

class B(d: Int) extends A(d)

и

class B(override val d: Int) extends A(d)

или оба эквивалентны?Если они разные, какой будет конкретный вариант использования для каждого из них?

Будет ли он другим, если A определен как class A(var d: Int)?

1 Ответ

9 голосов
/ 12 июля 2011

Для vals семантической разницы нет.Однако может быть разница в сгенерированном байт-коде .В частности, если метод, определенный в производном классе, ссылается на d, он ссылается на параметр конструктора d, а не на val с тем же именем.Это реализовано с помощью дополнительного закрытого поля, созданного для производного класса.

Для переменных равно a разница в поведении .Без переопределения любые методы, которые ссылаются на d из производного класса, будут ссылаться на параметр конструктора, в то время как вызывающие, ссылающиеся на d извне класса, получат поле.В этом случае два значения могут различаться (если значение изменилось с момента создания).

Вот сеанс, который демонстрирует поведение с переменной:

scala> class A(var d: Int)
defined class A

scala> class B(d: Int) extends A(d) { override def toString = "d: " + d }
defined class B

scala> val b = new B(1)
b: B = d: 1

scala> b.d = 2

scala> b.d
res1: Int = 2

scala> b
res2: B = d: 1

Этот вопрос связан: Идиоматический способ Scala для работы с именами полей базовых и производных классов? .

...