Bootstrap

【Golang】封装、继承、接口、多态

*本文笔记参考:b站【尚硅谷】Golang入门到实战教程

案例:写一个简单的AMT程序,实现存取款和查询功能。

package main
​
import (
    "fmt"
)
​
type Pay struct {
    Account string
    Pwd     string
    Money   float64
}
​
func (pay *Pay) SaveMoney(num float64, pwd string) {
    if pwd != pay.Pwd {
        fmt.Println("密码输入错误")
    } else {
        pay.Money += num
        fmt.Println("存款成功~, 您的余额为", pay.Money)
    }
}
​
func (pay *Pay) TakeMoney(num float64, pwd string) {
    if pwd != pay.Pwd {
        fmt.Println("密码输入错误")
    } else if num > pay.Money {
        fmt.Println("余额不足!")
    } else {
        pay.Money -= num
        fmt.Println("取款成功~, 您的余额为", pay.Money)
    }
}
​
func (pay *Pay) SeeMoney(pwd string) {
    if pwd != pay.Pwd {
        fmt.Println("密码输入错误")
    } else {
        fmt.Println("余额为:", pay.Money)
    }
}
​
func main() {
    var pay = Pay{"nongye", "123456", 100}
    var action int
    var count float64
    var pwdd string
Loop:
    for {
        fmt.Print("请输入要执行的操作:\n1:存款\n2:取款\n3:查询\n4:退出\n")
        fmt.Scanln(&action)
        switch action {
        case 1:
            fmt.Print("请输入要存的金额:")
            fmt.Scanln(&count)
            fmt.Print("请输入密码:")
            fmt.Scanln(&pwdd)
            pay.SaveMoney(count, pwdd)
        case 2:
            fmt.Print("请输入要取的金额:")
            fmt.Scanln(&count)
            fmt.Print("请输入密码:")
            fmt.Scanln(&pwdd)
            pay.TakeMoney(count, pwdd)
        case 3:
            fmt.Print("请输入密码:")
            fmt.Scanln(&pwdd)
            pay.SeeMoney(pwdd)
        case 4:
            break Loop
        }
    }
}
//输出
输入要执行的操作:
1:存款
2:取款
3:查询
4:退出
1
请输入要存的金额:200
请输入密码:123456
存款成功~, 您的余额为 300
请输入要执行的操作:
1:存款
2:取款
3:查询
4:退出
2
请输入要取的金额:50
请输入密码:123456
取款成功~, 您的余额为 250
请输入要执行的操作:
1:存款
2:取款
3:查询
4:退出
4

1、面向对象编程三大特性

1)封装

把抽象出的字段和对字段的操作封装在一起,数据被保护在内部,程序的其他包只有通过被授权的操作(方法),才能对字段进行操作。

(1)封装的优点

  1. 隐藏实现细节;

  2. 可以对数据进行验证,保证安全合理。

(2)如何体现封装

  1. 对结构体中的属性进行封装;

  2. 通过方法、包,实现封装。

(3)封装的实现步骤

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

  2. 给结构体所在包提供一个工厂模式的函数,首字母大写,类似构造函数;

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

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

//model/person.go
package model
​
import "fmt"
​
type person struct {
    Name   string
    age    int
    salary int
}
​
//写一个工厂模式的函数,相当于构造函数
func NewPerson(name string) *person {
    return &person{
        Name: name,
    }
}
​
//为了访问age和salary,编写一对Set***和Get***的方法
func (per *person) SetAge(age int) {
    if age > 0 && age < 120 {
        per.age = age
    } else {
        fmt.Println("年龄范围不正确")
    }
}
​
func (per *person) GetAge() int {
    return per.age
}
​
func (per *person)
;