Scala概述(三)统一的对象模型(1)

3.       统一的对象模型

Scala采用了一种纯粹的面向对象的模型,如同Smalltalk一样:每一个值都是对象,每一个操作都是消息传递。

 

3.1.    类(Classes) 

1(原文为Figure 2,但图上是Figure 1——译注)展示了Scala的类层次结构。每一个类都继承自scala.AnyAny的子类可以划分为两个主要范畴(Categories),值类型(values classes)继承自scala.AnyVal,引用类型(reference classes)继承自scala.AnyRef。每一种Java的基本数据类型都对应于一种值类型,通过预定义的类型别名进行映射,而AnyRef则对应于Java环境中的根类:java.lang.Ojbect。引用类型的实例一般是通过指向堆中的一个对象的指针来实现的,而值类型则是直接表示的,不通过指针引用。两种类型对象可以相互转换,例如将一个值类型实例看做是根类Any的实例时,此时的装箱(boxing)操作及其逆操作是自动完成的,无需额外编码。

       需要注意的是,值类型的类空间是平面的,即所有值类型继承自scala.AnyVal,但他们相互之间没有继承关系。作为替代,值类型之间有视图(即隐式类型转换,详见第9节)。我们曾经考虑另一种方式,即值类型之间相互继承,例如可以让Int类型继承自Float,而不是采用隐式类型转换。最终我们没有这样选择,主要是因为我们希望保持一点:将一个值解释为一个子类型的实例时,其表现形式不应与将其解释为其父类型的实例时相异。此外,我们还希望保证:对于任意两个类型S<:TST的子类型——译注),S的每一个实例都应当满足1

x.asInstanceOf[T].asInstanceOf[S] = x

       (由于浮点数是非精确表示的,因此类型转换有可能带来精度的损失,例如:目前Scala当中Integer.MAX_VALUE-1=2147483646这样的值经过toFloattoInt两次转换后就得到了2147483647——译注)

整个类层次结构的最底层有两个类型:scala.Nullscala.NothingNull是所有引用类型的子类,它只有一个实例,就是对象null。由于Null不是值类型的子类,所以null也不属于任何值类型,例如:将null赋值给一个int型变量是不可能的。

Nothing则是所有其他类型的子类,这个类没有任何实例。即便如此,它仍然可以作为类型参数而体现其存在价值。例如:Scalalibrary定义了一个值Nil,它是List[Nothing]的实例,由于Scalalist是协变(covariant)的,从而对于所有类型TNil都是List[T]的实例。(协变的概念在后文有介绍,这里不进行说明了——译注)

等词(“==”操作符)被设计为与类型的表现无关。对于值类型,它表示自然意义(数值、布尔值)上的相等,对于引用类型,它实际上相当于java.lang.Objectequals方法的别名。该方法本身被定义为引用相等,但可以被子类重新实现,用于表示子类在自然意义上的相等概念。例如:装箱后的值类型可以重新实现==用于比较被装箱的数值。而在Java中,==对于引用类型永远表示引用相等,虽然这样实现起来很容易,但却带来了很严重的一致性问题:两个本来相等的值装箱后再用==比较,可能就不再相等了。

有些情况下需要使用引用相等而非自定义比较,例如Hash-consingHash构建),因为此时性能至关重要。对以这种情况,AnyRef类型定义了另一个方法,eq,与java的“==”相同,实现的是引用相等的比较,但不同的是它不能被子类重载。



1 asInstanceOfScala标准的类转换方法,在Scala.Any中定义

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值