Scala:重载方法和字段及定义参数化字段

开发 后端
本文节选自Martin Odersky,Lex Spoon和Bill Venners所著,Regular翻译的《Programming in Scala》的第十章。Scala是一种针对 JVM 将函数和面向对象技术组合在一起的编程语言。

重载方法和字段

统一访问原则只是Scala在对待字段和方法方面比Java更统一的一个方面。另一个差异是Scala里,字段和方法属于相同的命名空间。这使得字段重载无参数方法成为可能。比如说,你可以改变类ArrayElement中contents的实现,从一个方法变为一个字段,而无需修改类Element中contents的抽象方法定义,如展示在代码10.4中的那样:

  1. class ArrayElement(conts: Array[String]) extends Element {  
  2.  val contents: Array[String] = conts  
  3. }  

代码 10.4 用字段重载无参数方法

51CTO编辑推荐:Scala编程语言专题

这个ArrayElement的版本里,字段contents(用val定义)完美地实现了类Element里的无参数方法contents(用def定义)。

另一方面,Scala里禁止在同一个类里用同样的名称定义字段和方法,而在Java里这样做被允许。例如,下面的Java类能够很好地编译:

  1. // 在Java里的代码  
  2. class CompilesFine {  
  3.  private int f = 0;  
  4.  public int f() {  
  5.   return 1;  
  6.  }  
  7. }  
但是相应的Scala类将不能编译:

  1. class WontCompile {  
  2.  private var f = 0  // 编译不过,因为字段和方法重名  
  3.  def f = 1 
  4. }  

通常情况下,Scala仅为定义准备了两个命名空间,而Java有四个。Java的四个命名空间是字段,方法,类型和包。与之相对,Scala的两个命名空间是:

 值(字段,方法,包还有单例对象)

 类型(类和特质名)

Scala把字段和方法放进同一个命名空间的理由很清楚,因为这样你就可以使用val重载无参数的方法,这种你在Java里做不到的事情。Scala里包共享了与字段和方法相同的命名空间的原因是为了让你能除了仅仅引用类型名以及单例对象的字段和方法之外,还能直接引用包。这同样是你在Java中无法做到的。

定义参数化字段

再次考虑上一节中展示的ArrayElement类的定义。它有一个参数conts,其唯一目的是被复制到contents字段。选择conts这个参数的名称只是为了让它看上去更像字段名contents而不会与它发生实际冲突。这是一种“代码味道”,一个表明或许某些不必须的荣誉和重复在你代码中出现的信号。

你可以通过在单一的参数化字段:parametric field定义中组合参数和字段避免这种代码味道,展示在代码10.5中:

  1. class ArrayElement(  // 请注意,小括号  
  2.  val contents: Array[String]  
  3. extends Element  

代码 10.5 定义contents为参数化字段

注意现在contents参数前缀了val。这是在同一时间使用相同的名称定义参数和字段的一个简写方式。尤其特别的是,类ArrayElement现在拥有一个可以从类外部访问的,(不能重新赋值的)字段contents。字段使用参数值初始化。就好象类被写成如下的方式,其中x123是参数的任意未曾用过的名字:

  1. class ArrayElement(x123: Array[String]) extends Element {  
  2.  val contents: Array[String] = x123  
  3. }  

同样也可以使用var前缀类参数,这种情况下相应的字段将能重新被赋值。最终,还有可能添加如private,protected,protected修饰符,可以授权给子类访问,将在第13章详细描述。或override这类的修饰符到这些参数化字段上,就好象你可以在其他类成员上做的事情。比方说,考察下列类定义:

  1. class Cat {  
  2.  val dangerous = false 
  3. }  
  4. class Tiger(  
  5.  override val dangerous: Boolean,  
  6.  private var age: Int  
  7. extends Cat  

Tiger的定义是以下包括重载成员dangerous和private成员age的类定义替代写法的简写:

  1. class Tiger(param1: Boolean, param2: Int) extends Cat {  
  2.  override val dangerous = param1  
  3.  private var age = param2  
  4. }  

两个成员都初始化自相应的参数。我们任意选择了这些参数名,param1和param2。重要的是它们不会与范围内的任何其它名称冲突。

【相关阅读】

  1. Scala程序中的扩展类
  2. 在Scala中定义无参数方法
  3. 学习Scala的二维布局库和抽象类
  4. Scala学习:叫名参数by-name parameter
  5. Scala:如何编写新的控制结构

 

责任编辑:book05 来源: Artima
相关推荐

2009-07-20 16:56:51

Scala类的定义

2009-07-21 12:47:04

Scala私有字段定义操作符

2009-07-22 07:53:00

Scala无参数方法

2009-07-21 13:54:55

Scala重载方法隐式转换

2010-11-23 15:27:00

MySQL添加字段

2010-09-02 09:29:02

SQL删除字段

2024-09-23 16:55:18

C#代码开发

2010-09-28 14:27:35

SQL定义Xml

2010-11-22 11:38:08

MySQL添加字段

2009-07-21 12:24:01

Scala先决条件添加字段

2009-08-27 10:06:15

Scala的构造方法

2009-07-21 17:21:57

Scala定义函数

2024-02-22 08:06:45

JSON策略解析器

2009-07-21 09:31:00

Scala基本类型文本

2009-12-11 10:42:00

Scala讲座类定义构造函数

2009-07-08 16:52:29

ScalaScala教程

2010-09-28 16:22:23

SQL ntext字段

2010-10-08 12:03:03

修改mysql字段

2010-09-28 14:46:45

SQL Xml字段

2009-07-09 00:25:00

Scala参数化
点赞
收藏

51CTO技术栈公众号