Я задал вопрос ранее: here, и хотя я принял ответ, я все еще очень далек от понимания, поэтому я немного углубился, и я пишу еще один вопрос.Пожалуйста, помогите мне понять переопределение val в scala
Поведение переоценки val в scala меня удивляет. Например, если этот код:
class A {
val name = "AAAAA"
}
class B extends A {
override val name = "BBBBB"
}
, если я говорю:
object Atest extends App {
val b = new B
println(b.name)
val a = b.asInstanceOf[A]
println(a.name)
}
Я ожидаю
BBBBB
AAAAA
, но я получаю
BBBBB
BBBBB
Я просто пытаюсь см. значение AAAAA, которое, я думаю, A должно хранить где-то , Поэтому я стараюсь:
class A {
val name = "AAAAA"
def showSuper {
println(name)
}
}
и:
val b = new B
val a = b.asInstanceOf[A]
b.showSuper
a.showSuper
, но я все еще получаю:
BBBBB
BBBBB
Так что я стараюсь делать взглянуть на то, что Scala фактически генерируя из моих классов:
scalac -Xprint:all A.scala
дает мне
class A extends Object {
private[this] val name: String = _;
<stable> <accessor> def name(): String = A.this.name;
def <init>(): p3.A = {
A.super.<init>();
A.this.name = "AAAAA";
()
}
};
class B extends p3.A {
private[this] val name: String = _;
override <stable> <accessor> def name(): String = B.this.name;
def <init>(): p3.B = {
B.super.<init>();
B.this.name = "BBBBB";
()
}
}
Звонок на B.super происходит до того, как B.this.name даже установится, и A четко устанавливает свое имя на AAAAA.
Что происходит? Почему, когда я переопределяю значение val, могу ли я не видеть значение A (или он получает значение B)? Каков механизм, которым это происходит? Как я могу увидеть этот механизм - есть ли фрагмент исходного кода scala, который показывает мне, почему это происходит?
Большое спасибо
EDIT: Предназначенный, чтобы добавить, что если я использую javap взглянуть на байткод, это ясно показывает, что А и В имеют свою собственную копию переменной имя:
$ javap -private A
Compiled from "A.scala"
public class p3.A extends java.lang.Object{
private final java.lang.String name;
public java.lang.String name();
public p3.A();
}
$ javap -private B
Compiled from "A.scala"
public class p3.B extends p3.A{
private final java.lang.String name;
public java.lang.String name();
public p3.B();
}
Итак, это не значит, что A и B должны делиться одной и той же переменной - каждый из них может использовать свою собственную копию.
[Этот ответ] (http://stackoverflow.com/questions/12358426/how-to-use-asinstanceof-properly-in-scala) может быть информативным – bwroga
Спасибо, но я не думаю, что это что-то делать с литьем. В моем примере выше, даже b.showSuper, я ожидал бы показать AAAAA, потому что он явно вызывает метод суперкласса, в котором указано поле A (или, по крайней мере, мне кажется, как минимум) – Bruce