- 项目开发流程
- 项目需求
- 项目界面
- 项目代码实现
- 先使用面向过程,后改为面向对象
项目需求
- 模拟实现基于文本界面的《家庭记账软件》
- 该软件能够记录家庭的收入、支出,并能够打印收支明细表
- 项目界面(类似于ATM机上的功能)
面向过程
import ( “fmt” )
func main() { // 声明变量,接收用户输入菜单项 key := “” // 声明变量,控制是否退出for loop := true
// 定义账户余额blance := 1000.0// 每次收支的金额money := 0.0//收支说明note := ""// 定义一个变量,表示是否存在收支记录flag := false// 收支详情,使用字符串记录// 当有收支记录的时候,只需要对 details 拼接即可details := "收支\t账户金额\t收支金额\t说明"// 显示主菜单for {fmt.Println("***********************家庭收支记账软件***********************")fmt.Println(" 1、收支明细")fmt.Println(" 2、登记收入")fmt.Println(" 3、登记支出")fmt.Println(" 4、退出软件")fmt.Print("请选择(1-4): ")fmt.Scanln(&key)switch key {case "1":if !flag {fmt.Println("目前为止,你还没有收支记录,来一笔吧🎈")} else {fmt.Println("***********************当前收支明细记录***********************")fmt.Println(details)}case "2":fmt.Println("***********************登记收入***********************")fmt.Println("本次收入金额: ")fmt.Scanln(&money)fmt.Println("本次收入说明: ")fmt.Scanln(¬e)blance += moneydetails += fmt.Sprintf("\n收入\t%v\t\t%v\t\t%v", blance, money, note)flag = truecase "3":fmt.Println("***********************登记支出***********************")fmt.Println("本次支出金额")fmt.Scanln(&money)if money > blance {fmt.Println("余额不足啦")break}blance -= moneyfmt.Println("本次收入说明: ")fmt.Scanln(¬e)details += fmt.Sprintf("\n支出\t%v\t\t%v\t\t%v", blance, money, note)flag = truecase "4":fmt.Println("你确定退出吗,请输入:Y(是)/N(否)")choice := ""for {fmt.Scanln(&choice)if choice == "Y" || choice == "N" {break}fmt.Println("你的输入有误,请重新输入:Y/N")}if choice == "Y" {loop = false}}if !loop {break}fmt.Println()fmt.Println()}fmt.Println("你退出了家庭记账软件🤞")
}
<a name="nF1Ye"></a># 面向过程修改成面向对象抽象思维<br />封装-继承-多态<a name="qFYYh"></a>## 思路分析1. 把记账软件的功能,封装到一个结构体中,然后调用该结构的方法,来实现**记账**,**显示明细**。结构体的名字 **FamilyAccount**2. 再通过在 **main** 方法中,创建结构体 **FamilyAccount 实例**,实现记账即可。3. 代码不需要重写,只需要重新组织<a name="T3ziY"></a>## 代码实现<a name="kL8ea"></a>### familyAccount/utils/familyAccount.go```go// 面向对象的方式实现 家庭记账软件// 封装、继承、多态package utilsimport ("fmt")type FamilyAccount struct {// 声明必须的字段// 声明字段,接收用户输入菜单项key string// 声明字段,控制是否退出forloop bool// 定义账户余额blance float64// 每次收支的金额money float64//收支说明note string// 定义一个字段,表示是否存在收支记录flag bool// 收支详情,使用字符串记录// 当有收支记录的时候,只需要对 details 拼接即可details string// details := "收支\t账户金额\t收支金额\t说明"}// 编写一个工厂模式的构造函数,返回 FamilyAccountfunc NewFamilyAccount() *FamilyAccount {// 给定初始值return &FamilyAccount{key: "",loop: true,blance: 1000.0,money: 0.0,note: "",flag: false,details: "收支\t账户金额\t收支金额\t说明",}}// 将每个菜单的功能封装成一个方法// 明细func (account *FamilyAccount) ShowDetails() {if !account.flag {fmt.Println("目前为止,你还没有收支记录,来一笔吧🎈")} else {fmt.Println("***********************当前收支明细记录***********************")fmt.Println(account.details)}}// 登记收入方法func (account *FamilyAccount) Income() {fmt.Println("***********************登记收入***********************")fmt.Println("本次收入金额: ")fmt.Scanln(&account.money)fmt.Println("本次收入说明: ")fmt.Scanln(&account.note)account.blance += account.moneyaccount.details += fmt.Sprintf("\n收入\t%v\t\t%v\t\t%v", account.blance, account.money, account.note)account.flag = true}// 登记支出方法func (account *FamilyAccount) Pay() {fmt.Println("***********************登记支出***********************")fmt.Println("本次支出金额")fmt.Scanln(&account.money)if account.money > account.blance {fmt.Println("余额不足啦")// break}account.blance -= account.moneyfmt.Println("本次收入说明: ")fmt.Scanln(&account.note)account.details += fmt.Sprintf("\n支出\t%v\t\t%v\t\t%v", account.blance, account.money, account.note)account.flag = true}// 退出方法func (account *FamilyAccount) Exit() {fmt.Println("你确定退出吗,请输入:Y(是)/N(否)")choice := ""for {fmt.Scanln(&choice)if choice == "Y" || choice == "N" {break}fmt.Println("你的输入有误,请重新输入:Y/N")}if choice == "Y" {account.loop = false}}// 给 FamilyAccount 结构体绑定方法// 显示主菜单func (account *FamilyAccount) MainMenu() {for {fmt.Println("***********************家庭收支记账软件***********************")fmt.Println(" 1、收支明细")fmt.Println(" 2、登记收入")fmt.Println(" 3、登记支出")fmt.Println(" 4、退出软件")fmt.Print("请选择(1-4): ")fmt.Scanln(&account.key)switch account.key {case "1":account.ShowDetails()case "2":account.Income()case "3":account.Pay()case "4":account.Exit()}if !account.loop {break}fmt.Println()fmt.Println()}fmt.Println("你退出了家庭记账软件🤞")}
familyAccount/main/main.go
// 面向对象方式完成调用package mainimport (_ "fmt""go_code/familyAccount/utils")func main() {// account := utils.NewFamilyAccount()// fmt.Println("account = ", *account)// true 1000 0 false 收支 账户金额 收支金额 说明}utils.NewFamilyAccount().MainMenu()}


