本文讨论一下在Scala语言里,字段(Fields)是如何实现的
字段实际上是getter/setter方法
在Scala里,字段是通过var或val关键字来定义的。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》
时间: 2024-10-11 03:38:06