一、封装介绍
封装(encapsulation)就是把抽象出的字段和对字段的操作封装在一起,数据被保护在内部,程序的其它包只有通过被授权的操作(方法),才能对字段进行操作。
二、对封装的理解和使用封装好处
1、 隐藏代码具体实现细节
2)、提可以对数据进行验证,保证安全合理(比如年龄(Age))
三、如何体现封装
1) 对结构体中的属性进行封装
2) 通过方法,包 实现封装
四、封装的实现步骤
1、将结构体、字段(属性)的首字母小写(不能导出了,其它包不能使用,类似private)
2、 给结构体所在包提供一个工厂模式的函数,首字母大写。类似一个构造函数
3、提供一个首字母大写的Set方法(类似其它语言的public),用于对属性判断并赋值
func (var 结构体类型) SetXxx(形参列表) (返回值列表) {
//对数据验证,进行处理 var.字段名
}
4、提供一个首字母大写的Get方法(类似其它语言的public),用于获取属性的值
func (var 结构体的类型) GetXxx() 返回值 {
return var.字段
}
特别说明:在Golang开发中并没有特别强调封装,这点并不像Java. 所以提醒学过java 的朋友,无需用java的语法特性来看待Golang, Golang本身对面向对象的特性做了简化的.
五、快速入门案例
银行账户案例:
1)创建程序,在model包中定义Account结构体:在main函数中体会Golang的封装性。
2) Account结构体要求具有字段:账号(长度在6-10之间)、余额(必须>20)、密码(必须是六位)
3) 通过SetXxx的方法给Account 的字段赋值 通过GetXxx方法获取字段的值。(同学们自己完
4) 将前面的Account单独的放在model包,并改进即可。
5) 在main函数中测试
代码如下:
model/account.go
package model
import (
"fmt"
)
// 名字:Account
// 属性/字段
// 账号, 余额, 密码...
// 行为/方法
// 存钱
// 取钱
// 查询..
type account struct {
accountNo string
money float64
pwd string
}
//工厂模式
func checkField(accountNo string, money float64, pwd string) bool {
//先对值进行验证
if len(accountNo) < 6 || len(accountNo) > 10 {
fmt.Println("账号长度不对")
return false
}
if money <= 20 {
fmt.Println("余额不对")
return false
}
if len(pwd) != 6 {
fmt.Println("密码需要为6位")
return false
}
return true
}
func NewAccount(accountNo string, money float64, pwd string) *account {
if !checkField(accountNo , money , pwd) {
return nil
}
return &account{
accountNo : accountNo,
money : money,
pwd : pwd,
}
}
//克隆..
func CloneAccount(account *account) *account {
return &account{
accountNo : account.accountNo,
money : account.money,
pwd : account.pwd,
}
}
//给accountNo 方法
func (a *account) GetAccountNo() string {
return a.accountNo
}
//账号不能修改,因此不提供Set..
func (a *account) GetPwd() string {
return a.pwd
}
func (a *account) SetPwd(pwd string) bool {
if len(pwd) != 6 {
fmt.Println("密码需要为6位")
return false
} else {
a.pwd = pwd
return true
}
}
//对Money的封装
func (a *account) Deposite(money float64, pwd string) {
if pwd != a.pwd {
fmt.Println("密码不正确")
return
}
if money <= 0 {
fmt.Println("存入的金额不对")
return
}
//存款
a.money += money
fmt.Println("恭喜,存款ok")
}
func (a *account) WithDraw(money float64, pwd string) {
if pwd != a.pwd {
fmt.Println("密码不正确")
return
}
if money <= 0 || money > a.money {
fmt.Println("取款金额不对..")
return
}
//取款
a.money -= money
fmt.Println("恭喜,取款ok")
}
func (a *account) Query(pwd string) {
if pwd != a.pwd {
fmt.Println("密码不正确")
return
}
//你的余额
fmt.Println("你的余额", a.money)
}
main/main.go
package main
import (
"go_code/chapter11/encapsulation/model"
)
func main() {
//使用一把
account := model.NewAccount("gh000001", 99999.9, "000000")
account.Deposite(10, "000000")
account.Query("000000")
account.WithDraw(8000, "000000")
account.Query("000000")
}