go语言笔记(六)面向对象_封装
封装encapsulation
封装就是把抽象出的字段和对字段的操作封装在一起,数据被保护在内部。
程序的其他包只有通过被授权的操作(方法)才能对字段进行操作。
封装的作用
1.隐藏实现细节
2.对数据进行验证,保证安全合理
封装的实现
1.结构体、字段名首字母小写,使其他包不能使用
2.给结构体所在包提供一个工厂模式的函数,首字母大写
3.提供一个首字母大写的Set方法,用于对属性判断并赋值
func (a Type) Set(形参列表) (返回值列表) {
//加入数据验证的业务逻辑
a.字段 = 参数
}
4.提供一个首字母大写的Get方法,用于获取属性的值
func (a Type) Get(形参列表) (返回值列表) {
return a.字段
}
封装快速入门案例
程序person.go,不能随便查看人的年龄、工资等隐私,并对输入的年龄进行合理的验证。
设计:model包(person.go),main包(main.go,调用person结构体)
package model
import "fmt"
type person struct {
Name string
age int
sal float64
}
//写一个工厂模式函数
func NewPerson(name string) *person {
return &person{
Name: name,
}
}
//为了访问sal和age,编写一对Set和Get方法
func (p *person) SetAge(age int) {
if age > 0 && age < 150 {
p.age = age
}else {
fmt.Println("年龄范围不对")
}
}
func (p *person) GetAge() int {
return p.age
}
func (p *person) SetSal(sal float64) {
if sal >= 3000 && sal <= 30000 {
p.sal = sal
}else {
fmt.Println("薪水范围不对")
}
}
func (p *person) GetSal() float64{
return p.sal
}
package main
import (
"fmt"
"shangguigu/demo_encapsulation/model"
)
func main () {
p := model.NewPerson("小王")
p.SetAge(23)
p.SetSal(7000)
fmt.Println(p,p.Name,p.GetAge(),p.GetSal())
}
课堂练习
1.创建程序,在 model 包中定义 Account 结构体:在 main 函数中体会 Golang 的封装性。
2.Account 结构体要求具有字段:账号(长度在 6-10 之间)、余额(必须>20)、密码(必须是六
3.通过 SetXxx 的方法给 Account 的字段赋值。
4.在 main 函数中测试
package model
import "fmt"
type account struct {
Num string
psw string
rst float64
}
func Newaccount(num, psw string, rst float64) *account {
if len(num) < 6 || len(num) > 10 {
fmt.Println("账号长度必须为6到10之间")
return nil
}
if len(psw) != 6 {
fmt.Println("密码长度必须为6")
return nil
}
if rst < 20 {
fmt.Println("余额不得少于20")
return nil
}
return &account{
Num: num,
psw: psw,
rst: rst,
}
}
func (a *account) SetPsw(p string) {
if len(p) != 6 {
fmt.Println("密码长度必须为6")
}else {
a.psw = p
}
}
func (a *account) Deposit(m float64) {
a.rst += m
}
func (a *account) Withdraw(m float64) {
if a.rst - m < 20 {
fmt.Println("余额不得少于20")
}else {
a.rst -= m
}
}
func (a *account) GetRst() float64 {
return a.rst
}
func (a *account) GetPsw() string {
return a.psw
}
package main
import (
"fmt"
"shangguigu/exercise_encapsulation/model"
)
func main() {
var n, p string
var b float64
fmt.Println("请输入账号:")
fmt.Scanln(&n)
fmt.Println("请输入密码:")
fmt.Scanln(&p)
fmt.Println("请输入金额:")
fmt.Scanln(&b)
myacc := model.Newaccount(n,p,b)
if myacc == nil{
return
}
for {
fmt.Println("请选择操作 1:查询余额 2:存款 3:取款 4:设置密码 5:退出")
var flag int
fmt.Scanln(&flag)
switch flag {
case 1:
fmt.Println(myacc.GetRst())
case 2:
var m float64
fmt.Println("请输入要存入的金额:")
fmt.Scanln(&m)
myacc.Deposit(m)
case 3:
var m float64
fmt.Println("请输入要提取的金额:")
fmt.Scanln(&m)
fmt.Println("请输入密码")
var psw string
fmt.Scanln(&psw)
if psw == myacc.GetPsw() {
myacc.Withdraw(m)
}else {
fmt.Println("密码错误")
}
case 4:
fmt.Println("请输入旧密码")
var jm string
fmt.Scanln(&jm)
if jm == myacc.GetPsw() {
fmt.Println("请输入新密码")
var xm string
fmt.Scanln(&xm)
myacc.SetPsw(xm)
}else {
fmt.Println("密码错误")
}
case 5:
break
}
}
}
运行结果如下
请输入账号:
1234567
请输入密码:
666666
请输入金额:
30
请选择操作 1:查询余额 2:存款 3:取款 4:设置密码 5:退出
1
30
请选择操作 1:查询余额 2:存款 3:取款 4:设置密码 5:退出
2
请输入要存入的金额:
50
请选择操作 1:查询余额 2:存款 3:取款 4:设置密码 5:退出
1
80
请选择操作 1:查询余额 2:存款 3:取款 4:设置密码 5:退出
3
请输入要提取的金额:
60
请输入密码
666666
请选择操作 1:查询余额 2:存款 3:取款 4:设置密码 5:退出
1
20
请选择操作 1:查询余额 2:存款 3:取款 4:设置密码 5:退出
4
请输入旧密码
666666
请输入新密码
777777
请选择操作 1:查询余额 2:存款 3:取款 4:设置密码 5:退出
5