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

2018-09-28 18:26 更新

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

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

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

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

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

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

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

從使用這個類的客戶代碼來說,這兩個實現(xiàn)是等價的,唯一的差別是使用成員變量的方法調(diào)用速度要快些,因為字段值在類被初始化的時候被預(yù)計算,而方法調(diào)用在每次調(diào)用的時候都要計算。換句話說,字段在每個 Element 對象上需要更多的內(nèi)存空間。

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

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

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

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

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

總結(jié)起來,Scala 里定義不帶參數(shù)也沒有副作用的方法為無參數(shù)方法,也就是說,省略空的括號,是鼓勵的風格。另一方面,永遠不要定義沒有括號的帶副作用的方法,因為那樣的話方法調(diào)用看上去會像選擇一個字段。

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

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號