Scala 類和對象 (三)

2018-09-28 18:16 更新

類和對象 (三)

有了前面的 Scala 的基本知識,本篇介紹如何定義完整功能的 Scala 類定義。本篇著重介紹如果定義 Functional objects (函數(shù)化對象或是方程化對象),函數(shù)化對象指的是所定義的類或?qū)ο蟛话魏慰梢孕薷牡臓顟B(tài)。本篇定義了一個有理數(shù)類定義的幾個不同版本以介紹 Scala 類定義的幾個特性:類參數(shù)和構(gòu)造函數(shù),方法,操作符,私有成員,重載,過載,條件檢查,引用自身。

Rational類定義規(guī)范

首先,我們回憶下有理數(shù)的定義:一個有理數(shù)(rational)可以表示成個分?jǐn)?shù)形式: n/d, 其中 n 和 d 都是整數(shù)(d 不可以為 0),n 稱為分子(numberator),d 為分母(denominator)。和浮點數(shù)相比,有理數(shù)可以精確表達(dá)一個分?jǐn)?shù),而不會有誤差。

因此我們定義的 Rational 類支持上面的有理數(shù)的定義。支持有理數(shù)的加減乘除,并支持有理數(shù)的規(guī)范表示,比如 2/10,其規(guī)范表示為 1/5。分子和分母的最小公倍數(shù)為 1。

定義Rational

有了有理數(shù)定義的實現(xiàn)規(guī)范,我們可以開始設(shè)計類 Rational,一個好的起點是考慮用戶如何使用這個類,我們已經(jīng)決定使用“Immutable”方式來使用 Rational 對象,我們需要用戶在定義 Rational 對象時提供分子和分母。因此我們可以開始定義 Rational 類如下:

class Rational( n:Int, d:Int)

可以看到和 Java 不同的,Scala 的類定義可以有參數(shù),稱為類參數(shù),如上面的 n,d。Scala 使用類參數(shù),并把類定義和主構(gòu)造函數(shù)合并在一起,在定義類的同時也定義了類的主構(gòu)造函數(shù)。因此 Scala 的類定義相對要簡潔些。

Scala 編譯器會編譯 Scala 類定義包含的任何不屬于類成員和類方法的其它代碼,這些代碼將作為類的主構(gòu)造函數(shù),比如我們定義一條打印消息作為類定義的代碼:

scala> class Rational (n:Int, d:Int) {
     |    println("Created " + n + "/" +d)
     | }
defined class Rational
scala> new Rational(1,2)
Created 1/2
res0: Rational = Rational@22f34036

可以看到創(chuàng)建 Ratiaonal 對象時,自動執(zhí)行類定義的代碼(主構(gòu)造函數(shù))。

重新定義類的toString 方法

上面的代碼創(chuàng)建 Rational(1,2),Scala 編譯器打印出 Rational@22f34036,這是因為使用了缺省的類的 toString()定義(Object 對象的),缺省實現(xiàn)是打印出對象的類名稱+“@”+16 進(jìn)制數(shù)(對象的地址),顯示結(jié)果不是很直觀,因此我們可以重新定義類的 toString()方法以顯示更有意義的字符。

在 Scala 中,你也可以使用 override 來重載基類定義的方法,而且必須使用 override 關(guān)鍵字表示重新定義基類中的成員。比如:

scala> class Rational (n:Int, d:Int) {
     |    override def toString = n + "/" +d
     | }
defined class Rational
scala> val x= new Rational(1,3)
x: Rational = 1/3
scala> val y=new Rational(5,7)
y: Rational = 5/7

前提條件檢查

前面說過有理數(shù)可以表示為 n/d (其中 d,n 為證書,而 d 不能為 0),對于前面的 Rational 定義,我們?nèi)绻褂?0,也是可以的

scala> new Rational(5,0)
res0: Rational = 5/0

怎么解決分母不能為 0 的問題了,面向?qū)ο缶幊痰囊粋€優(yōu)點是實現(xiàn)了數(shù)據(jù)的封裝,你可以確保在其生命周期過程中是有效的。對于有理數(shù)的一個前提條件是分母不可以為 0,Scala 中定義為傳入構(gòu)造函數(shù)和方法的參數(shù)的限制范圍,也就是調(diào)用這些函數(shù)或方法的調(diào)用者需要滿足的條件。Scala 中解決這個問題的一個方法是使用 require 方法(require 方法為 Prede f對象的定義的一個方法,Scala 環(huán)境自動載入這個類的定義,因此無需使用 import 引入這個對象),因此修改 Rational 定義如下:

scala> class Rational (n:Int, d:Int) {
     |    require(d!=0)
     |    override def toString = n + "/" +d
     | }
defined class Rational
scala> new Rational(5,0)
java.lang.IllegalArgumentException: requirement failed
  at scala.Predef$.require(Predef.scala:211)
  ... 33 elided

可以看到如果再使用 0 作為分母,系統(tǒng)將拋出 IllegalArgumentException 異常。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號