Scala:重载方法和字段及定义参数化字段
创始人
2024-04-19 02:41:29
0

重载方法和字段

统一访问原则只是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:如何编写新的控制结构

 

相关内容

热门资讯

如何允许远程连接到MySQL数... [[277004]]【51CTO.com快译】默认情况下,MySQL服务器仅侦听来自localhos...
如何利用交换机和端口设置来管理... 在网络管理中,总是有些人让管理员头疼。下面我们就将介绍一下一个网管员利用交换机以及端口设置等来进行D...
施耐德电气数据中心整体解决方案... 近日,全球能效管理专家施耐德电气正式启动大型体验活动“能效中国行——2012卡车巡展”,作为该活动的...
Windows恶意软件20年“... 在Windows的早期年代,病毒游走于系统之间,偶尔删除文件(但被删除的文件几乎都是可恢复的),并弹...
20个非常棒的扁平设计免费资源 Apple设备的平面图标PSD免费平板UI 平板UI套件24平图标Freen平板UI套件PSD径向平...
德国电信门户网站可实时显示全球... 德国电信周三推出一个门户网站,直观地实时提供其安装在全球各地的传感器网络检测到的网络攻击状况。该网站...
为啥国人偏爱 Mybatis,... 关于 SQL 和 ORM 的争论,永远都不会终止,我也一直在思考这个问题。昨天又跟群里的小伙伴进行...
《非诚勿扰》红人闫凤娇被曝厕所... 【51CTO.com 综合消息360安全专家提醒说,“闫凤娇”、“非诚勿扰”已经被黑客盯上成为了“木...