0
点赞
收藏
分享

微信扫一扫

Go:关于封装的具体实现

go语言的封装,就是把抽象出的字段和对字段的操作封装在一起,数据被保护在内部,程序的其他包只有通过被授权的操作(方法),才能对字段进行操作。封装的好吃就是:1、可以隐藏实现的细节;2、可以对数据进行验证,保障安全合理。

主要体现在对结构体中的属性进行封装,通过方法或包 ,实现封装。其实现的步骤大致如下:

~ 将结构体、字段(属性)的首字母小写(意为不能导出,其他包也不能使用,类似private);

~ 为结构体所做的包提供一个工厂模式的函数,首字母大写。类似一个构造函数;

~ 提供一个首字母大写的Set方法(类似其他语言的public),用于对属性判断并赋值

~ 提供一个首字母大写的Get方法(类似其他语言的public),用于获取属性的值

案例演示:在model包中定义一个account结构体; 在main函数中实现Golang的封装性;可以实现存、取、查、修改和退出的功能。

account.go

//放在go_code/.../model 下
package model
import (
	"fmt"
)
//定义一个account结构体,首写字母为小写。不可导出也不能被其他包调用
type account struct {
	account string
	password string
	balance float64
}

//创建工厂模式的函数,类似构造函数,返回一个指针类型
func NewAccount(accNo string,pwd string,bal float64) *account {
	if len(accNo) < 6 || len (accNo) > 10 {
		fmt.Println("输入有误,账号长度必须在(6~10之间)...")
		return nil 
	}
	if len(pwd) != 6 {
		fmt.Println("输入有误,密码长度必须是6位...")
		return nil 
		
	}
	if bal < 20 {
		fmt.Println("输入有误,余额不得少于20元...")
		return nil 
	}
	return &account {
		account : accNo,
		password: pwd,
		balance : bal,
    }
}

//封装方法
func (acc *account) GetPass(pwd string) bool {
	if pwd != (*acc).password {
		fmt.Println("密码输入错误...")
		return false
	} 
	return true
}

func (acc *account) ResetPwd(pwd string) (bool,string){
	if len(pwd) != 6 {
		fmt.Println("输入的新密码位数不是6位...")
		return false,""
	} else {
		(*acc).password = pwd 
	}
	return true,(*acc).password
}

func (acc *account) SaveMoney(val float64) (bool,float64) {
	if val < 50 {
		fmt.Println("存入金额不得低于50元...")
		return false,0.0
	} else {
		(*acc).balance += val 
	}
	return true,(*acc).balance
}

func (acc *account) WithDraw(getMoney float64) (bool,float64){
	if getMoney > (*acc).balance || getMoney <= 0 {
		fmt.Println("输入的金额不对...")
		return false,0.0
	} else {
		(*acc).balance -= getMoney
	}
	return true,(*acc).balance
}

func (acc *account) CheckBal() (float64) {
	return (*acc).balance
}

main.go

//放在go_code/ .../main 中
package main

import (
	"fmt"
	"go_code/.../model" //引入model包中的account.go
)

func main() {
	var (
		accountNo string
		passwd    string
		val       int
		operator  int
		count     int
	)
	inputData := func() {
		fmt.Println("请输入卡号(长度在6~10之间)...")
		fmt.Scanln(&accountNo)

		fmt.Println("请输入密码(必须六位)...")
		fmt.Scanln(&passwd)

		fmt.Println("请输入初设的金额(不得低于20元)...")
		fmt.Scanln(&val)	
	}

    //初始化操作
	inputData()
	initAccount := model.NewAccount(accountNo, passwd, float64(val))

	//通过调用封装后的函数来验证密码
	inputPwdForVerify := func() bool {
		fmt.Println("请先输入密码...")
		fmt.Scanln(&passwd)
		isOk := initAccount.GetPass(passwd)
		return isOk
	}

//调用封装后的函数,来验证初始化是否成功
a:
	for {
		if initAccount != nil {
			fmt.Printf("创建成功~_~! 卡号:%v,密码:%v,余额:%.2f \n", accountNo, passwd, float64(val))
			break a
		} else {
			count++
			inputData()
			initAccount = model.NewAccount(accountNo, passwd, float64(val))
		}
		if count == 3 {
			fmt.Println("已连续3次创建失败,程序退出...")
			break a
		}	
	}

//通过调用封装后的方法,来进行各项操作	
b:
	for {
		fmt.Println("请选择服务项目: 1.存款;2.取款; 3.密码修改;4.查询余额;5.退出")
		fmt.Scanln(&operator)
		switch operator {
		case 1:
			if !inputPwdForVerify() {
				continue b
			} else {
				fmt.Println("请输入存入金额(金额不得低于50元)...")
				fmt.Scanln(&val)
			}
			isOk, newBal := initAccount.SaveMoney(float64(val))
			if isOk {
				fmt.Printf("您存入的金额为%.2f,当前余额为%.2f \n", float64(val), newBal)
			} else {
				continue b	
			}
			continue b
		case 2:
			if !inputPwdForVerify() {
				continue b
			} else {
				fmt.Println("请输入取款金额...")
				fmt.Scanln(&val)
			}
			isOk, value := initAccount.WithDraw(float64(val))
			if isOk {
				fmt.Printf("您存入的金额为%.2f,当前余额为%.2f \n", float64(val), value)
			} else {
				continue b	
			}
			continue b
		case 3:
			if !inputPwdForVerify() {
				continue b
			} else {
				fmt.Println("请设置您的新密码,密码位数不得低于六位...")
				fmt.Scanln(&passwd)
			}
			isOk,newPwd := initAccount.ResetPwd(passwd)
			if isOk {
				fmt.Printf("密码设置成功,当前密码为%v \n", newPwd)
			} else {
				continue b	
			}
			continue b
		case 4:
			if !inputPwdForVerify() {
				continue b
			} else {
				newBalance := initAccount.CheckBal()
				fmt.Printf("您当前的余额为%.2f \n",newBalance)
			}
			continue b
		case 5:
			break b
		default:
			fmt.Println("操作失败")
			break b
		}
	}
}

输出结果:

举报

相关推荐

0 条评论