您的位置:首页 > 其它

Programming In Scala笔记-第十一章、Scala中的类继承关系

2016-10-06 23:14 260 查看
  本章主要从整体层面了解Scala中的类层级关系。

一、Scala的类层级

  在Java中
Object
类是所有类的最终父类,其他所有类都直接或间接的继承了
Object
类。在Scala中所有类的最终父类为
Any
类,所以
Any
类中的所有方法都可以在Scala中任意类中使用。但是这并不是说Scala中的
Any
类就类似于Java中的
Object
类,Scala中真正地位类似于Java中
Object
类的是
AnyRef
类。

  在Scala中还提供了两个类
Null
Nothing
,这两个类在整个Scala类层级的最底层,其中
Nothing
类是所有类的最终子类,
Nothing
类直接或间接继承其他任何类。

1、整体类层级图

  下图展示了Scala中的整体类层级图,其中
Any
位于最顶端,
Nothing
位于最底端。

  


2、Any类结构

  这一节中我们看一下
Any
类中定义了哪些方法。

  从Scala API文档中可以看到,
Any
类中提供
==, !=, equals, ##, hashCode, toString, isInstanceOf[TO], asInstanceOf[TO]
共八个方法。其中
==, !=, ##, asInstanceOf[TO], isInstanceOf[TO]
final
类型的,不能在子类中使用
override
关键字进行重写。在Scala中对于
==
方法,如果判断对象为引用类型,调用该方法等同于调用该对象的
equals
方法。

  

  
Any
类的两个直接子类是
AnyVal
AnyRef
,其中
AnyVal
是Scala中的值类型,比如
Double, Float
等的直接父类,注意这里
Unit
类型也是
AnyVal
类型的直接子类。而
AnyRef
则是Scala中所有引用类型类的父类,类似于Java中的
Object
类。

  

二、原始类型是如何实现的

  对Java熟悉的话,应该会对
int
类型和
Integer
类型有一定的了解。在Scala中对
Int
类型变量的处理也和Java中类似,
Int
类型提供加或乘这样的简单操作,但如果需要调用
toString
方法或者将
Int
值赋给
Any
类型变量时,
Int
型变量会自动转化成
Integer
类型。这个过程和Java中的自动装箱有些类似。

  我们首先看一下下面这段Java代码

boolean isEqualInt(int x, int y) {
return x == y;
}
System.out.println(isEqual(421, 421));

boolean isEqualInteger(Integer x, Integer y) {
return x == y;
}
System.out.println(isEqualInteger(421, 421));


  代码在IDEA中的运行结果如下

  


  
isEqualInt
方法接收到传入的两个整数后直接判断值是否相等,得到的结果为
true
。但是
isEqualInteger
方法接收到整型参数后,哪怕是值相等的整型参数,也会首先自动装箱成两个
Integer
类型对象,并且两个
Integer
对象是不同的对象,调用
==
方法得到的结果为
false


  再看一段Scala中的代码,仍然定义两个函数、

def isEqualInt(x: Int, y: Int) = x == y
isEqualInt(421, 421)

def isEqualAny(x: Any, y: Any) = x == y
isEqualAny(421, 421)


  运行结果如下,

  


  由于在Scala中,引用类型调用
==
方法等同于调用
equals
方法,所以
isEqualAny
方法的返回结果也是
true


  那么,如果在Scala中就是需要判断两个引用类型对象的引用是否相等,应该怎么办?在
AnyRef
类中,Scala提供了
eq
ne
方法。

val x = new String("abc")
val y = new String("abc")

x == y
x eq y
x ne y


  运行结果如下,

  


三、底层类型

  这里主要讨论上面的类继承关系图中最底层的两个类
scala.Null
scala.Nothing
。Scala中可以使用者两个类统一的处理一些面向对象编程的边界情况。

1、Null类

  比如说在Java中,
null
值是没有对应的类型的,如果将某个变量赋值
null
然后调用
getClass
方法,会报一个
NullPointerException
,如下图所示。

  


  但是在Scala中
null
值的类型为
Null
Null
类型所有引用类型类的子类,而不是值类型的子类。所以,不能将
null
赋值给
Int
类型变量。

val i: Int = null


  执行结果如下,

  


2、Nothing类

  
Nothing
类位于Scala类继承关系中的最底层,是Scala中任何类的子类,包括上面的
Null
类。

  由于
Nothing
类是任何类的子类,所以可以以如下形式来使用该类。

def error(message: String): Nothing =
throw new RuntimeException(message)

def divide(x: Int, y: Int): Int =
if (y != 0) x / y
else error("can't divide by zero")


  在前面我们知道了,Scala中的执行语句都有一个返回结果类型,对于
if
语句来说,返回类型为两个分支的公共父类,而这里
if
分支的返回类型为
Int
Int
else
的返回类型
Nothing
的父类,所以
divide
方法的最终返回类型仍然是
Int
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: