所有的类都继承于 Any Any 有两大派:AnyVal 值类型(基本数据类型),AnyRef 引用类型
因为继承于 Any,所有有一些基本方法,比如:==, !=, equals, hashCode
, 其中 ==, !=
为 final,不可重写,但是与 equals 等价,因此重写 equals 即可重写 ==
或 !=
AnyVal 表示值类型,比较特殊,举个例子 Int 它是一个伴生对象,但是它的伴生类是 final abstract,因此无法直接通过new 操作符构造实例。 只能通过字面量的形式来创建实例对象。
Int 有很多方法,但是这些方法可能不是来自于 Int 对象本身,比如方法 min、max、until、to
和 abs
都定义在类 scala.runtime.RichInt
里,并且有一个从类 Int 到 RichInt 的隐式转换。当你在 Int 上调用没有定义在 Int 上但定义在 RichInt 上的方法时,这个转换就被应用了。
此外,除了 Int,Boolean 等这些常见的值类型,还有一个特殊的值类型:Unit
。它对应 java 中的 void,它只有一个实例值()
。
Null
代表 null 引用,它是所有引用类的子类(每个由 AnyRef
派生的类)。它和值类型不兼容,无法将一个 null 值赋给一个整型变量。
Nothing
是所有类的子类,然后这个类型没有任何实例(也就是没有任何值对应 Nothing
类型)。常见用法:抛异常的时候,返回值定义为 Nothing
,可以充分运用多态特性而不产生编译时异常。
// 比如 sys 有一个 error 方法
def error(message: String): Nothing =
throw new RuntimeException(message)
//在此定义函数的返回值为 Int
def divide(x:Int,y:Int):Int={
if(y!=0) x/y
else error("Cannot divide by Zero")
}
Nil
类型
case object Nil extents List[Nothing]
因为 trait List
具有协变型,所以 Nil 是所有 List(比如 List[Int]、List[Double]
)的一个具体类型。
-
小说明 AnyVal 使用的是 abstract class AnyVal,而 AnyRef 使用的是 trait AnyRef。因为 java中的 class 是单继承,所以使用 abtract class 可以很好地避免子类继承多个父类。而 trait 本身是可以多继承的,所以子类可以继承多个 AnyRef。
-
类型关系运算符 A =:= B A 必须和 B相等 A <:< B A 必须是 B的子类
import scala.reflect.runtime.universe._
typeOf[Int] =:= typeOf[Int]
typeOf[Int] <:< typeOf[Any]