封裝
從資料的角度:封裝 (encapsulation) 就是把抽象出的資料和對資料的操作封裝在一起,資料被保護在內部,程式的其它部分只有通過被授權的操作(成員方法),才能對資料進行操作
從模組的角度:封裝就是將需要重複使用的邏輯封裝成共有的模組,提高開發效率,減少重複性編碼
封裝的理解和好處(以資料為例)
-
隱藏實現細節
-
既可以對資料進行驗證,又保證資料的安全合理
如何體現封裝(以資料為例)
- 通過成員方法實現對屬性的封裝,通過包實現對類的封裝
封裝的實現步驟(以資料為例)
-
將屬性進行私有化
-
提供一個公共的
set
方法,用於對屬性判斷並賦值 -
Java 和 Scala 提供的訪問許可權修飾符
def setXxx(引數名 : 型別) : Unit = {
//加入資料驗證的業務邏輯
屬性 = 引數名
}
複製程式碼
- 提供一個公共的
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)"
}
複製程式碼
細節
Scala
中為了簡化程式碼的開發,在類中宣告屬性時,自動提供對應的setter/getter
方法(方法名為屬性名_&eq/屬性名
);如果屬性訪問許可權宣告為private
,對應setter/getter
方法的訪問許可權是private
;如果屬性宣告省略訪問許可權(編譯器會自動為其加上public
訪問許可權),對應setter/getter
方法的訪問許可權是private
- 如果僅僅只是對一個屬性進行簡單的
set 和 get
,只需要宣告該屬性即可;訪問屬性直接使用物件.屬性
即可(實質上是呼叫編譯器自動生成的getter
方法);設定屬性直接使用物件.屬性=xxx
即可(實質上是呼叫編譯器自動生成的setter
方法)