scala重写类参数

mic*_*yer 3 parameters overriding scala class

之前已经讨论过这个话题,但没有得到令人满意的答复(在我看来).请考虑以下scala代码:

class A(a:Int) { val _a=a }
class A1(val a:Int) { val _a=a }

class B(a:Int) extends A(a)                    // OK
class C(val a:Int) extends A(a)                // OK

class B1(a:Int) extends A1(a)                  // OK
class C1(val a:Int) extends A1(a)              // fails
class D1(override val a:Int) extends A1(a)     // OK  
Run Code Online (Sandbox Code Playgroud)

我认为将class参数声明为val只会对构造函数调用产生影响:复制参数而不是传递引用.但是,在每种情况下,类字段都被分配为val.它是否正确?

现在我不明白为什么我们在最后一行需要override关键字.请注意,我们不会将类声明为案例类,因此不会自动分配字段.

最后有一个很好的理由为什么人们甚至想要用val类参数定义类似A1的类?

提前感谢所有回复.

Did*_*ont 6

我认为将class参数声明为val只会对构造函数调用产生影响:复制参数而不是传递引用.但是,在每种情况下,类字段都被分配为val.它是否正确?

一点也不.

如果构造函数中存在val或var,则会导致在类中声明具有相同名称的val或var,并在构造时为其指定构造函数参数.否则,如果构造函数参数在初始化之外使用,即在方法中,则仍可在类中创建(私有)val.

在A1类中,成员_a真的没用,因为如果你写的话

class A1(val a: Int) {} 
Run Code Online (Sandbox Code Playgroud)

它相当于

class A1(someFreshName: Int) {val a = someFreshName}
Run Code Online (Sandbox Code Playgroud)

所以在C1,你试图宣布一个新成员a,而已经有一个.因此覆盖.在您的特定实例中,两个成员都具有相同的值,但您可以做(也许不是一个好主意)

class C1(override val a: Int) extends A1(12)
Run Code Online (Sandbox Code Playgroud)

然后,新成员a将构造函数参数作为值,前一个a将具有值12并被隐藏(但仍然,编写的代码A1将访问它).