Cris 的 Scala 筆記整理(八):物件導向中級-封裝

Cris就是我發表於2018-12-20

封裝

​ 從資料的角度:封裝 (encapsulation) 就是把抽象出的資料和對資料的操作封裝在一起,資料被保護在內部,程式的其它部分只有通過被授權的操作(成員方法),才能對資料進行操作

​ 從模組的角度:封裝就是將需要重複使用的邏輯封裝成共有的模組,提高開發效率,減少重複性編碼

封裝的理解和好處(以資料為例)
  1. 隱藏實現細節

  2. 既可以對資料進行驗證,又保證資料的安全合理

如何體現封裝(以資料為例)
  1. 通過成員方法實現對屬性的封裝,通過包實現對類的封裝
封裝的實現步驟(以資料為例)
  1. 將屬性進行私有化

  2. 提供一個公共的 set 方法,用於對屬性判斷並賦值

  3. Java 和 Scala 提供的訪問許可權修飾符

def  setXxx(引數名 : 型別) : Unit = {
		//加入資料驗證的業務邏輯
		屬性 = 引數名   
	}
複製程式碼
  1. 提供一個公共的 get 方法,用於獲取屬性的值
def getXxx() [: 返回型別] = {
	return 屬性
    }
複製程式碼
Scala 封裝案例演示

建立一個員工類,對其必要屬性進行私有化,並限制年齡只能為 [0,120]

object StuffDemo {
  def main(args: Array[String]): Unit = {
    val stuff = new Stuff(sex = 'M')
    println(stuff) // Stuff(2000.0, 18, M)

    stuff.setAge(24)
    println(stuff) // Stuff(2000.0, 24, M)

    stuff.setAge(190)
    println(stuff) // Stuff(2000.0, 24, M)
  }

}

/**
  * 可以在主構造器中定義屬性的預設值,甚至是設定屬性的訪問許可權,但是失去了對屬性的控制(解決方式是可以在呼叫構造方法前對設定的屬性進行驗證)
  *
  * @param salary
  * @param age
  * @param sex
  */
class Stuff(private var salary: Double = 2000, val sex: Char) {
  private var age: Int = 18

  def setAge(age: Int): Unit = {
    if (age >= 0 && age <= 120) {
      this.age = age
    }
  }

  override def toString = s"Stuff($salary, $age, $sex)"
}
複製程式碼
細節
  1. Scala 中為了簡化程式碼的開發,在類中宣告屬性時,自動提供對應的 setter/getter 方法(方法名為 屬性名_&eq/屬性名);如果屬性訪問許可權宣告為 private,對應 setter/getter 方法的訪問許可權是 private;如果屬性宣告省略訪問許可權(編譯器會自動為其加上 public 訪問許可權),對應 setter/getter 方法的訪問許可權是 private
  2. 如果僅僅只是對一個屬性進行簡單的 set 和 get,只需要宣告該屬性即可;訪問屬性直接使用 物件.屬性 即可(實質上是呼叫編譯器自動生成的 getter 方法);設定屬性直接使用 物件.屬性=xxx 即可(實質上是呼叫編譯器自動生成的 setter 方法)

相關文章