首页 > 代码库 > 探索Scala(7)-- 字段

探索Scala(7)-- 字段

本文讨论一下在Scala语言里,字段(Fields)是如何实现的

字段实际上是getter/setter方法

在Scala里,字段是通过varval关键字来定义的。var字段是可读写的,val字段是只读的。下面是一个简单的例子:

class MyObj {
    var intVar = 1
    val strVal = "str"
}
反编译之后,可以得到下面的Java代码:

public class MyObj {    private int intVar = 1;    private final String strVal = "str";    public int intVar() {return intVar;}    public void intVar_$eq(int intVar) {this.intVar = intVar;}    public String strVal() {return strVal;}}
可见:

  • 对于var字段,Scala编译器会生成相应的Java字段和一对儿getter/setter方法
  • 对于val字段,编译器会生成final字段和getter方法
  • getter方法和字段同名
  • setter方法为:字段名_$eq

抽象字段

因为字段实际上就是getter/setter方法,所以在Scala里,可以定义抽象字段(只要不赋初始值即可):

abstract class AbstractObj {
    var intVar: Int
    val strVal: String
}
反编译之后,得到下面Java代码:

public abstract class AbstractObj {
    public abstract int intVar();    public abstract void intVar_$eq(int intVar);    public abstract String strVal();}

字段重写

只有val字段可以被override,如下所示:

class MySubObj extends MyObj {
    override val strVal = "substr"
}
反编译后,得到下面的Java代码:

public class MySubObj extends MyObj {
    private final String strVal = "substr";    @Override     public String strVal() {        return strVal;    }}
如果不想让val字段被子类重写,可以给字段加上final关键字:
class MyObj {
    var intVar = 1
    final val strVal = "str"
}

private字段

字段默认是public,但是即使改成private,Scala仍然会给字段生成getter/setter方法。如果字段只在对象内使用,可以把字段的访问级别设置成private[this],这样,字段的含义就跟Java一样了(而且拥有更小的可见范围--只有对象自己可见):

class ObjectPrivateFields {
    private[this] var intVar = 1
    private[this] val strVal = "str"
}

生成JavaBean风格Getter/Setter方法

如果想生成JavaBean风格的getter/setter方法,可以给字段打上@BeanProperty注解:

import scala.beans.BeanProperty
class ScalaBean {
    @BeanProperty var intVar = 1
    @BeanProperty val strVal = "str"
}

参考资料

《Scala for the Impatient》




探索Scala(7)-- 字段