學(xué)習(xí)Scala的二維布局庫和抽象類
二維布局庫
作為本章運行的例子,我們將創(chuàng)造一個制造和渲染二維布局元素的庫。每個元素將代表一個填充字符的長方形。方便起見,庫將提供名為“elem”的工廠方法來通過傳入的數(shù)據(jù)構(gòu)造新的元素。例如,你將能通過工廠方法采用下面的寫法創(chuàng)建帶有字串的元素:
- elem(s: String): Element
51CTO編輯推薦:Scala編程語言專題
正如你所見,元素將以名為Element的類型為模型。你將能在元素上調(diào)用above或beside,傳入第二個元素,從而得到合并了這兩個的新元素。例如,下面的表達(dá)式將構(gòu)建一個包含兩列,每列高度為二,的更大的元素:
打印這個表達(dá)式的結(jié)果將是:
- val column1 = elem("hello") above elem("***")
- val column2 = elem("***") above elem("world")
- column1 beside column2
在對象能通過簡單的部件及組合操作符的幫助被構(gòu)建的系統(tǒng)中,布局元素是個好的例子。本章里,我們將定義類使得元素對象能被構(gòu)建自數(shù)組,行記錄,以及長方形——簡單部件。我們還將定義組合操作符above和beside。這種組合操作符也經(jīng)常被稱為組合子:combinator,因為它們把某些區(qū)域的元素組合成新的元素。
- hello ***
- *** world
以組合子的方式思考問題通常是實現(xiàn)庫的設(shè)計的好方法:它能回報以考慮在應(yīng)用域構(gòu)建對象的基礎(chǔ)方法。什么是簡單對象?用什么方式能讓更多有趣的對象通過簡單對象構(gòu)造出來?組合子是怎么掛在一起的?什么是最通用的組合?它們滿足任何有趣的規(guī)則嗎?如果你對這些問題都有好的答案,你的庫設(shè)計就在正軌上了。
抽象類
我們的***個任務(wù)就是定義代表布局元素的類型Element。由于元素是二維的字符長方形,包括成員,指向布局元素內(nèi)容的contents,是合情合理的。內(nèi)容可以被表達(dá)成字串?dāng)?shù)組,這里每個字串代表一行。因此,contents返回的結(jié)果類型就是Array[String]。代碼10.1展示了它看起來的樣子。
這個類里,contents被聲明為沒有實現(xiàn)的方法。換句話說,方法是類Element的抽象:abstract成員。具有抽象成員的類本身必須被聲明為抽象的,只要在class關(guān)鍵字之前加上abstract修飾符即可:
代碼 10.1 定義抽象方法和類
- abstract class Element {
- def contents: Array[String]
- }
abstract修飾符說明類或許有沒實現(xiàn)的抽象成員。結(jié)果,你不能實例化抽象類。如果你嘗試這么做,你會得到編譯器錯誤:
- abstract class Element ...
本章后面你會看到如何創(chuàng)建類Element的子類,你將能實例化它們因為它們補(bǔ)上了缺失的contents定義。
- scala> new Element
- < console>:5: error: class Element is abstract;
- cannot be instantiated
- new Element
- ˆ
請注意類Element的contents方法并沒帶有abstract修飾符。如果方法沒有實現(xiàn)(也就是說,沒有等號或方法體),它就是抽象的。不像Java,方法的聲明中不需要(或允許)抽象修飾符。擁有實現(xiàn)的方法被稱為具體的:concrete。
另一個術(shù)語用法需要分辨聲明:declaration和定義:definition。類Element聲明了抽象方法contents,但當(dāng)前沒有定義具體方法。然而下一節(jié),我們要定義一些具體方法來加強(qiáng)Element。
【相關(guān)閱讀】