官术网_书友最值得收藏!

6.2 構建Rational實例

要定義Rational類,首先可以考慮一下使用者如何創建新的Rational對象。由于已經決定Rational對象是不可變的,因此我們將要求使用者在構造Rational實例時就提供所有需要的數據(也就是分子和分母)。我們從下面的設計開始:

關于這段代碼,首先要注意的一點是,如果一個類沒有定義體,則并不需要給出空的花括號(只要你想,當然也可以)。類名Rational后的圓括號中的標識符nd被稱作類參數class parameter)。Scala編譯器將會采集這兩個類參數,并且創建一個主構造方法primary constructor),接收同樣的這兩個參數。

不可變對象的設計取舍

與可變對象相比,不可變對象具有若干優勢和一個潛在的劣勢。首先,不可變對象通常比可變對象更容易推理,因為不可變對象沒有隨著時間變化而變化的復雜的狀態空間。其次,可以相當自由地傳遞不可變對象,而對于可變對象,在傳遞給其他代碼之前,你可能需要對其進行保護式的復制。再次,假如有兩個并發的線程同時訪問某個不可變對象,則它們沒有機會在對象被正確構造以后破壞其狀態,因為沒有線程可以改變某個不可變對象的狀態。最后,不可變對象可以被安全地用作哈希表里的鍵。舉例來說,如果某個可變對象在被添加到HashSet以后改變了,則當你下次再檢索該HashSet的時候,可能就找不到這個對象了。

不可變對象的主要劣勢是它有時候需要復制一個大的對象圖,而實際上也許一個局部的更新就能滿足要求。在某些場景下,不可變對象可能用起來比較別扭,同時會帶來性能瓶頸。因此,類庫對于不可變的類也提供可變的版本這樣的做法并不罕見。例如,StringBuilder類就是對不可變的String類的一個可變的替代。我們將在第16章更詳細地介紹Scala中可變對象的設計。

注意

這個Rational示例突出顯示了Java和Scala的一個區別。在Java中,類有構造方法,構造方法可以接收參數;而在Scala中,類可以直接接收參數,且Scala的表示法更為精簡(類定義體內可以直接使用類參數,不需要定義字段并編寫將構造方法參數賦值給字段的代碼)。這樣可以大幅度節省樣板代碼,尤其是對小型的類而言。

Scala編譯器會將你在類定義體中給出的非字段或方法定義的代碼編譯進類的主構造方法中。舉例來說,可以像這樣來打印一條調試消息:

對于這段代碼,Scala編譯器會將println調用放在Rational類的主構造方法中。這樣一來,每當你創建一個新的Rational實例時,都會觸發println打印出相應的調試消息:

當你實例化那些接收參數的類(如Rational類)時,可以選擇不寫new關鍵字。這樣的代碼編寫方式被稱作“通用應用方法”(universal apply method)。例如:

主站蜘蛛池模板: 博爱县| 连城县| 札达县| 孝昌县| 彭山县| 永兴县| 高密市| 中方县| 丹棱县| 石渠县| 政和县| 晋州市| 浮梁县| 汪清县| 普兰店市| 江口县| 奉化市| 达尔| 六安市| 藁城市| 桦川县| 玉林市| 龙江县| 玛纳斯县| 通化市| 樟树市| 乐安县| 龙岩市| 江都市| 昌图县| 鄂托克前旗| 永德县| 兴业县| 夏津县| 睢宁县| 永靖县| 水富县| 凤翔县| 股票| 香河县| 信阳市|