Scala 組合和繼承–定義無參數(shù)方法

2018-09-28 18:26 更新

組合和繼承–定義無參數(shù)方法

作為下一步,我們將向 Element 添加顯示寬度和高度的方法,height 方法返回 contents 里的行數(shù)。width 方法返回第一行的長(zhǎng)度,或如果元素沒有行記錄,返回零。

abstract class Element { 
  def contents: Array[String] 
  def height: Int = contents.length 
  def width: Int = if (height == 0) 0 else contents(0).length 
}

請(qǐng)注意 Element 的三個(gè)方法沒一個(gè)有參數(shù)列表,甚至連個(gè)空列表都沒有,這種無參數(shù)方法在 Scala 里是非常普通的。相對(duì)的,帶有空括號(hào)的方法定義,如 def height(): Int,被稱為空括號(hào)方法:(empty-paren method)。

Scala的慣例是在方法不需要參數(shù)并且只是讀取對(duì)象狀態(tài)時(shí)使用無參數(shù)方法。

此外,我們也可以使用成員變量來定義 width 和 height,例如:

abstract class Element { 
  def contents: Array[String] 
  val height = contents.length 
  val width = if (height == 0) 0 else contents(0).length 
}

從使用這個(gè)類的客戶代碼來說,這兩個(gè)實(shí)現(xiàn)是等價(jià)的,唯一的差別是使用成員變量的方法調(diào)用速度要快些,因?yàn)樽侄沃翟陬惐怀跏蓟臅r(shí)候被預(yù)計(jì)算,而方法調(diào)用在每次調(diào)用的時(shí)候都要計(jì)算。換句話說,字段在每個(gè) Element 對(duì)象上需要更多的內(nèi)存空間。

特別是如果類的字段變成了訪問函數(shù),且訪問函數(shù)是純函數(shù)的,就是說它沒有副作用并且不依賴于可變狀態(tài),那么類 Element 的客戶不需要被重寫。這稱為統(tǒng)一訪問原則: uniform access principle, 就是說客戶代碼不應(yīng)受通過字段還是方法實(shí)現(xiàn)屬性的決定的影響。

Scala 代碼可以調(diào)用 Java 函數(shù)和類,而 Java 沒有使用“統(tǒng)一訪問原則”,因此 Java 里是 string.length(),不是 string.length。為了解決這個(gè)問題,Scala 對(duì)于無參數(shù)函數(shù)和空括號(hào)函數(shù)的使用上并不是區(qū)分得很嚴(yán)格。也就是,你可以用空括號(hào)方法重載無參數(shù)方法,并且反之亦可。你還可以在調(diào)用任何不帶參數(shù)的方法時(shí)省略空的括號(hào)。例如,下面兩行在 Scala里都是合法的:

Array(1, 2, 3).toString 
"abc".length

原則上 Scala 的函數(shù)調(diào)用中可以省略所有的空括號(hào)。但如果使用的函數(shù)不是純函數(shù),也就是說這個(gè)不帶參數(shù)的函數(shù)可能修改對(duì)象的狀態(tài)或是我們需要利用它的一些副作用(比如打印到屏幕,讀寫 I/o),一般的建議還是使用空括號(hào),比如:

"hello".length // 沒有副作用,所以無須() 
println() // 最好別省略()

總結(jié)起來,Scala 里定義不帶參數(shù)也沒有副作用的方法為無參數(shù)方法,也就是說,省略空的括號(hào),是鼓勵(lì)的風(fēng)格。另一方面,永遠(yuǎn)不要定義沒有括號(hào)的帶副作用的方法,因?yàn)槟菢拥脑挿椒ㄕ{(diào)用看上去會(huì)像選擇一個(gè)字段。

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

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)