鍍金池/ 教程/ Scala/ Scala 的類層次關(guān)系
包對象
Ordered Trait
組合和繼承–定義 final 成員
基本數(shù)據(jù)類型
Match 表達(dá)式
類和對象 (三)
操作基本數(shù)據(jù)類型
for 表達(dá)式
組合和繼承–重載成員函數(shù)和方法
類和對象 (二)
組合和繼承–定義 factory 對象
組合和繼承–多態(tài)和動態(tài)綁定
Trait 的基本概念
if 表達(dá)式
組合和繼承–抽象類
函數(shù)–函數(shù)字面量的一些簡化寫法
while 循環(huán)
組合和繼承–使用組合還是繼承?
訪問控制修飾符
Trait 示例–Rectangular 對象
組合和繼承–定義參數(shù)化成員變量
組合和繼承–定義無參數(shù)方法
類和對象 (一)
函數(shù)–閉包
函數(shù)–類成員函數(shù)
Scala 基本數(shù)據(jù)類型的實現(xiàn)方法
try 表達(dá)式處理異常
選擇瘦接口還是胖接口設(shè)計?
組合和繼承–小結(jié)
創(chuàng)建新的控制結(jié)構(gòu)
使用 import
為訪問控制修飾符添加作用域
Scala 的類層次關(guān)系
類和對象 (五)
傳名參數(shù)
柯里化函數(shù)
函數(shù)–頭等公民
組合和組合和繼承–定義 heighten 和 widen 函數(shù)
使用 Package–將代碼放入包中
隱含的 import
所有類的公共子類–底層類型
進(jìn)一步 Scala
函數(shù)–局部函數(shù)
引用包中的代碼
組合和繼承–使用 override 修飾符
組合和繼承–實現(xiàn)類 Element 的 above,beside 和 toString()方法
類和對象 (四)
函數(shù)–尾遞歸
沒有“break”和“continue”的日子
組合和繼承–調(diào)用基類構(gòu)造函數(shù)
減低代碼重復(fù)
函數(shù)–函數(shù)–可變參數(shù),命名參數(shù),缺省參數(shù)
起步 Scala
組合和繼承–擴(kuò)展類
函數(shù)–部分應(yīng)用的函數(shù)
開始神奇的 Scala編程之旅
組合和繼承–概述
Trait 用來實現(xiàn)可疊加的修改操作

Scala 的類層次關(guān)系

前面我們介紹了 Scala 的類的繼承,本篇我們介紹 Scala 語言自身定義的類的層次關(guān)系,在 Scala 中,所有的類都有一個公共的基類稱為 Any,此外還定義了所有類的子類 Nothing,下面的圖給出的 Scala定義的類層次關(guān)系的一個概要:

http://wiki.jikexueyuan.com/project/scala-development-guide/images/16.png" alt="" />

由于所有的類都繼承自 Any,因此 Scala 中的對象都可以使用==,!=,或 equals 來比較,使用##或 hashCode 給出 hash 值,使用 toString 轉(zhuǎn)為字符串。Any 的==和!=定位為 fianl,因此不可以被子類重載。==實際上和 equals 等價,!=和 equals 的否定形式等價,因此重載 equals 可以修改==和!=的定義。

根類 Any 有兩個子類:AnyVal 和 AnyRef。AnyVal 是 Scala 里每個內(nèi)建值類型的父類。有九個這樣的值類型:Byte,Short,Char,Int,Long,F(xiàn)loat,Double,Boolean 和 Unit。其中的前八個對應(yīng)到 Java 的基本數(shù)值類型,它們的值在運行時表示成 Java 的類型。Scala 里這些類的實例都寫成字面量。例如,42 是 Int 的實例,’x’是 Char 的實例,false 是 Boolean 的實例。值類型都被定義為即是抽象的又是 final 的,你不能使用 new 創(chuàng)造這些類的實例。

scala> new Int
<console>:8: error: class Int is abstract; cannot be instantiated
              new Int
              ^
scala> 

另一個值類,Unit,大約對應(yīng)于 Java 的 void 類型;被用作不返回任何有趣結(jié)果的方法的結(jié)果類型。 Unit 只有一個實例值,被寫作().

值類支持作為方法的通用的數(shù)學(xué)和布爾操作符。例如,Int 有名為+和*的方法,Boolean 有名為||和&&的方法。值類也從類 Any 繼承所有的方法。你可以在解釋器里測試:

scala> 42 toString
res3: String = 42
scala> 42.hashCode
res6: Int = 42

可以看到 Scala 的值類型之間的關(guān)系是扁平的,所有的值類都是 scala.AnyVal 的子類型,但是它們不是互相的子類。代之以它們不同的值類類型之間可以隱式地互相轉(zhuǎn)換。例如,需要的時候,類 scala.Int 的實例可以自動放寬(通過隱式轉(zhuǎn)換)到類 scala.Long 的實例。隱式轉(zhuǎn)換還用來為值類型添加更多的功能。例如,類型 Int 支持以下所有的操作:

scala> 42 max 43
res0: Int = 43
scala> 42 min 43
res1: Int = 42
scala> 1 until 5
res2: scala.collection.immutable.Range = Range(1, 2, 3, 4)
scala> 1 to 5 
res3: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3, 4, 5)
scala> 3.abs
res4: Int = 3
scala> (-3).abs
res5: Int = 3

這里解釋其工作原理:方法 min,max,until,to 和 abs 都定義在類 scala.runtime.RichInt 里,并且有一個從類 Int 到 RichInt 的隱式轉(zhuǎn)換。當(dāng)你在 Int 上調(diào)用沒有定義在 Int 上但定義在 RichInt 上的方法時,這個轉(zhuǎn)換就被應(yīng)用了。

類 Any 的另一個子類是類 AnyRef。這個是 Scala 里所有引用類的基類。正如前面提到的,在 Java 平臺上 AnyRef 實際就是類 java.lang.Object 的別名。因此 Java 里寫的類和 Scala 里寫的都繼承自 AnyRef。如此說來,你可以認(rèn)為 java.lang.Object 是 Java 平臺上實現(xiàn) AnyRef 的方式。因此,盡管你可以在 Java 平臺上的 Scala 程序里交換使用 Object 和 AnyRef,推薦的風(fēng)格是在任何地方都只使用 AnyRef。

Scala 類與 Java 類不同在于它們還繼承自一個名為 ScalaObject 的特別的 Marker Trait(Trait 我們在后面再進(jìn)一步解釋)。