【问题标题】:scala overriding class parametersscala覆盖类参数
【发布时间】:2014-10-18 01:17:14
【问题描述】:

这个话题之前已经讨论过,但没有得到满意的回答(在我看来)。 考虑以下 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  

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

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

终于有一个很好的理由为什么人们甚至想要用 val 定义一个像 A1 这样的类 类参数?

提前感谢所有回复。

【问题讨论】:

    标签: class scala parameters overriding


    【解决方案1】:

    我相信将类参数声明为 val 只有一个 对构造函数调用的影响:参数被复制而不是 传递参考。但是,在每种情况下,都会分配类字段 作为一个瓦尔。这是正确的吗?

    一点也不。

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

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

    class A1(val a: Int) {} 
    

    相当于

    class A1(someFreshName: Int) {val a = someFreshName}
    

    所以在C1 中,您正试图声明一个新成员a,而已经有一个。因此覆盖。 在您的特定情况下,两个成员将具有相同的值,但您可以做得很好(也许不是一个好主意)

    class C1(override val a: Int) extends A1(12)
    

    然后,新成员 a 将构造函数参数作为值,而之前的 a 将具有值 12 并被隐藏(但是,用 A1 编写的代码仍然可以访问它)。

    【讨论】:

    • 为什么我在class A1(val a:Any) {def test = a} ; class C1(override val a: Any) extends A1(12) {override def toString = s"$a:$test"} ; println(new C1("m")) 中得到m:mA1 would access it 是什么意思?
    猜你喜欢
    • 2011-07-27
    • 2012-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-18
    • 2012-05-20
    • 1970-01-01
    相关资源
    最近更新 更多