Scala的类层级:与Java类之异同
创始人
2024-04-19 04:50:53
0

Scala类层级图 

图释 11.1 Scala类层级图

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

图释11.1展示了Scala的类层级的大纲。层级的顶端是类Any,定义了包含下列的方法:

  1. final def ==(that: Any): Boolean  
  2. final def !=(that: Any): Boolean  
  3. def equals(that: Any): Boolean  
  4. def hashCode: Int  
  5. def toString: String  

因为每个类都继承自Any,Scala程序里的每个对象都能用==,!=或equals比较;用hashCode哈希;和用toString格式化。类Any里的等号和不等号方法,==和!=,被声明为final,因此它们不能在子类里面重载。实际上,==总是与equals相同,!=总是与equals相反。因此独立的类可以通过重载equals方法剪裁==或!=的意义。我们会在本章后面展示一个例子。

根类Any有两个子类:AnyVal和AnyRef。AnyVal是Scala里每个内建值类的父类。有九个这样的值类:Byte,Short,Char,Int,Long,Float,Double,Boolean和Unit。其中的前八个对应到Java的原始类型,它们的值在运行时表示成Java的原始值。Scala里这些类的实例都写成文本。例如,42是Int的实例,'x'是Char的实例,false是Boolean的实例。你不能使用new创造这些类的实例。这一点被“小伎俩”,值类都被定义为即是抽象的又是final的,强制贯彻。因此如果你写了:

  1. scala> new Int  

你就会得到:

  1. < console>:5: error: class Int is abstract; cannot be instantiated  
  2. new Int  
  3. ˆ  

另一个值类,Unit,大约对应于Java的void类型;被用作不返回任何有趣结果的方法的结果类型。Unit只有一个实例值,被写作(),在7.2节中讨论过。

正如第五章中解释过,值类支持作为方法的通用的数学和布尔操作符。例如,Int有名为+和*的方法,Boolean有名为||和&&的方法。值类也从类Any继承所有的方法。你可以在解释器里测试: 

  1. scala> 42.toString  
  2. res1: java.lang.String = 42 
  3. scala> 42.hashCode  
  4. res2: Int = 42 
  5. scala> 42 equals 42 
  6. res3: Boolean = true 

注意,值类的空间是扁平的;所有的值类都是scala.AnyVal的子类型,但是它们不是互相的子类。代之以它们不同的值类类型之间可以隐式地互相转换。例如,需要的时候,类scala.Int的实例可以自动放宽(通过隐式转换)到类scala.Long的实例。

正如5.9节中提到过的,隐式转换还用来为值类型添加更多的功能。例如,类型Int支持以下所有的操作:

  1. scala> 42 max 43 
  2. res4: Int = 43 
  3. scala> 42 min 43 
  4. res5: Int = 42 
  5. scala> 1 until 5 
  6. res6: Range = Range(1, 2, 3, 4)  
  7. scala> 1 to 5 
  8. res7: Range.Inclusive = Range(1, 2, 3, 4, 5)  
  9. scala> 3.abs  
  10. res8: Int = 3 
  11. scala> (-3).abs  
  12. res9: Int = 3 

这里解释其工作原理:方法min,max,until,to和abs都定义在类scala.runtime.RichInt里,并且有一个从类Int到RichInt的隐式转换。当你在Int上调用没有定义在Int上但定义在RichInt上的方法时,这个转换就被应用了。类似的“助推器类”和隐式转换存在于其它的值类。隐式转换将在第21章讨论细节。

类Any的另一个子类是类AnyRef。这个是Scala里所有引用类的基类。正如前面提到的,在Java平台上AnyRef实际就是类java.lang.Object的别名。因此Java里写的类和Scala里写的都继承自AnyRef。存在AnyRef别名代替使用java.lang.Object名称的理由是,Scala被设计成可以同时工作在Java和.Net平台。在.NET平台上,AnyRef是System.Object的别名。如此说来,你可以认为java.lang.Object是Java平台上实现AnyRef的方式。因此,尽管你可以在Java平台上的Scala程序里交换使用Object和AnyRef,推荐的风格是在任何地方都只使用AnyRef。

Scala类与Java类不同在于它们还继承自一个名为ScalaObject的特别的记号特质。理念是ScalaObject包含了Scala编译器定义和实现的方法,目的是让Scala程序的执行更有效。到现在为止,Scala对象包含了单个方法,名为$tag,用于内部以提速模式匹配。

【相关阅读】

  1. Scala中的Spiral程序:把代码都螺旋在一起
  2. Scala中变高变宽的实现:heighten和widen
  3. 学习Scala的定义工厂对象
  4. 如何实现Scala的above,beside和toString
  5. Scala学习:使用组合与继承

相关内容

热门资讯

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