Scala会根据你定义属性时候使用的关键字:var,val,private来选择是否自动生成getter和setter方法。并且不允许你重写Scala的setter和getter方法。如果你要重写这两个方法你会看到如下编译错误:
scala> :paste
// Entering paste mode (ctrl-D to finish)
class Person(private var name: String) {
def name = name
def name_=(aName: String) {name = aName}
}
// Exiting paste mode, now interpreting.
<console>:12: error: overloaded method name needs result type
def name = name
^
<console>:13: error: method name_= is defined twice
conflicting symbols both originated in file '<console>'
def name_=(aName: String) {name = aName}
^
Scala默认对于Person类的name属性,自动生成的getter和setter方法名分别是name和name_=。但是你可以变通的用另一种方式来避开Scala的setter和getter方法名规范,比如我们把name属性名改为_name那么这个时候Scala默认生成的getter和setter方法是_name和_name_=,你只要不用这两个方法名就可以了。
scala> :paste
// Entering paste mode (ctrl-D to finish)
class Person(private var _name: String) {
def name = _name
def name_=(aName: String) {_name = aName}
override def toString = s"name is $name"
}
// Exiting paste mode, now interpreting.
defined class Person
scala> val p = new Person("Li Ming")
p: Person = name is Li Ming
因为name属性是private var修饰的,所以它是可变,再加上我们定义了自己的getter方法。我们可以改变并获取name属性值。
scala> val p = new Person("Li Ming")
p: Person = name is Li Ming
scala> p.name = "Wang Wei"
p.name: String = Wang Wei
scala> p.name
res2: String = Wang Wei
我们来看一下反编译后的class文件中的getter和setter方法,你会看到一个getter方法:symbol();一个setter方法symbol_$eq。这就是Scala生成getter和setter的规范。
class Stock (var symbol: String)
public class Stock extends java.lang.Object{
public java.lang.String symbol();
public void symbol_$eq(java.lang.String);
public Stock(java.lang.String);
}
总结一下:重定义Scala默认生成的getter和setter方法,我们需要注意下面几点。
- 使用private var关键字修饰构造方法参数,一般在参数名前加上下划线“_”。
- 定义getter和setter方法:getter方法使用“参数名”命名;setter方法使用“参数名_="来命名。
一定记住要使用private关键字来修饰构造方法参数,否则Scala会生成一对默认的getter和setter方法。
scala> :paste
// Entering paste mode (ctrl-D to finish)
class Stock (var _symbol: String) {
def symbol = _symbol
def symbol_=(s: String) {
this._symbol = s
println(s"symbol was updated, new value is $symbol")
}
}
// Exiting paste mode, now interpreting.
defined class Stock
反编译生成的class文件,你会发现除了你自己定义的getter和setter方法外,Scala还为你生成了一对默认的getter和setter方法。
public class Stock extends java.lang.Object{
//Scala自动生成的getter和setter方法
public java.lang.String _symbol();
public void _symbol_$eq(java.lang.String);
//自定义的getter和setter方法
public java.lang.String symbol();
public void symbol_$eq(java.lang.String);
public Stock(java.lang.String);
}
使用private关键修饰后,反编译生成的class文件。
public class Stock extends java.lang.Object{
public java.lang.String symbol();
public void symbol_$eq(java.lang.String);
public Stock(java.lang.String);
}