1. scala在定义类的构造方法时,可以指定任意个数的参数,并且类没有主体时,就不需要指定一对空的花括号。一个简单的实例如下:
class Rational(n: Int, d: Int) {
override def toString = n +\"/\"+ d
}
object Main {
def main(args: Array[String]) {
val oneHalf = new Rational(1, 2)
println(\"oneHalf [\" + oneHalf + \"]\")
}
Rational类重写了toString方法,可是我们在类里并没有申明n和d字段,那它是怎么工作的呢?其实是scala编译器帮我们做了这一切,反编译Rational.class文件的类结构如下:
public class Rational{
private final int n;
private final int d;
public String toString()
{
return new StringBuilder()
.append(this.n).append(\"/\")
.append(BoxesRunTime.boxToInteger(this.d)).toString();
}
}
可以看到类里多了两个final成员字段:n和d。再向类里添加一个merge方法:
class Rational(n: Int, d: Int) {
override def toString = n +\"/\"+ d
def merge(that: Rational): Rational = {
new Rational(n + that.n, d + that.d)
}
}
如果直接运行merge方法会报错,因为类成员n和d是private类型。
2. 参数化字段:scala的参数化字段是在类的构造参数字段前面加val前缀,示例如下:
class Rational(val n: Int, val d: Int) {
override def toString = n +\"/\"+ d
def merge(that: Rational): Rational = {
new Rational(n + that.n, d + that.d)
}
}
此时的merge方法并不会操作,查看反编译的Rational.class文件结构如下:
public class Rational
{
private final int n;
private final int d;
public int n() { return this.n; }
public int d() { return this.d; }
public String toString()
{
return new StringBuilder().append(n())
.append(\"/\").append(BoxesRunTime.boxToInteger(d())).toString();
}
public Rational merge(Rational that)
{
return new Rational(n() + that.n(), d() + that.d());
}
}
从上图中可以看到,在定义了参数化字段后,scala在编译生成class文件时,不仅增加了成员字段,同时还增加了其或取值的方法,源文件的字段访问在编译成class文件时都变成了方法调用。此时merge方法可以正常运行。
3. 总结:scala的参数化字段就是在定义类的构造参数时,在其前面添加val前缀。这样scala会自动为这些参数生成类的成员字段,同时生成对应的取其值的方法。我们在scala源码类文件里,不用再定义额外的字段来保存类的构造参数,直接使用即可。
版权声明
本文仅代表作者观点,不代表百度立场。
本文系作者授权百度百家发表,未经许可,不得转载。



