【问题标题】:Scala limitation on constructor-defined attributesScala 对构造函数定义属性的限制
【发布时间】:2012-03-07 00:39:42
【问题描述】:

在 Scala 中,可以在构造函数中定义类属性。但是一旦在那里声明它们,就不能再改变行为(getter 和 setter),就像在类主体中声明时那样?

例子:

class MyExample(var attribute : String)
{
    def attribute() //trying to override getter <- doesn't work
}

class MyExample(theAttribute : String)
{
   def attribute = theAttribute //overriding default accessor (was var)
}

如果不可能,为什么会这样?当您向人们展示他们可以通过在构造函数中设置 var 或 val 轻松创建属性,而不关心 getter 和 setter(如果需要时可以更改),最终发现实际上应该避免使用这些,这似乎令人困惑一种便利。

【问题讨论】:

    标签: class scala constructor attributes


    【解决方案1】:

    让我们想象一下可以覆盖生成的访问器方法:

    class MyExample(var attribute : String)
    {
        def attribute() = attribute + "abc" // won't compile!
    }
    

    如果没有进一步的限定,就无法判断方法体中的名称 attribute 是指类字段还是递归地指方法本身。

    按照 Scala 的设计,方法和字段属于同一个命名空间,这称为 Uniform Access Principle,它提供了在不破坏外部接口的情况下更改内部实现的能力。

    初始实现可能是:

    class MyExample(val attribute : String)
    

    然后改成:

    class MyExample (attr :String) {
       def attribute = attr toUpperCase 
    }
    

    然后

    class MyExample(var attribute : String)
    

    或者

    class MyExample(attr : String) { 
        def attribute = attr toUpperCase 
        def attribute_= (a : String) { attr = a + "abc" } 
    }
    

    全部不破坏任何依赖代码。

    当字段被定义为构造函数的一部分时,自动生成的访问器方法是语法糖。糖简化了快速原型设计并有助于保持代码简洁。尽管如此,当你想添加更多内容时,你必须使用完整的语法。

    【讨论】:

    • 非常感谢您的出色回答。对于初学者来说,做这些事情并不是很明显,而且书籍通常只介绍常见的情况。
    猜你喜欢
    • 1970-01-01
    • 2021-06-19
    • 2021-12-17
    • 2011-08-28
    • 2018-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-11
    相关资源
    最近更新 更多