面向对象编程三大特性-封装

1. 封装的基本介绍

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

  1. 隐藏实现细节
  2. 可以对数据进行验证,保证安全合理(Age)

2. 封装的实现步骤

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

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

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

    1
    2
    3
    //加入数据验证的业务逻辑var.字段=参数
    func (var 结构体类型名) SetXxx(参数列表) (返回值列表){
    }
  4. 提供一个首字母大写的Get方法(类似于其他语言的public),用于获取属性的值。

    1
    2
    3
    func (var 结构体类型名) GetXxx() {
    return var.age;
    }

3. 实例

需求:

不能随便查看人的年龄,工资等隐私,并对输入的年龄进行合理的验证。

设计:

model 包(person.go) ,main 包(main.go 调用 Person 结构体)

image-20240520213624553

3.1 定义mod

1
2
cd encap
go mod init encap

3.2 person.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
package model

import "fmt"

type person struct {
Name string
age int //其他包不能直接访问
sal float64
}

// 写一个工厂模式的函数,相当于构造函数
func NewPerson(name string) *person {
return &person{
Name: name,
}
}

// 为了访问age和sal编写一堆SetXxx的方法和GetXxx的方法
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
}

3.3 main.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package main

import (
"encap/model"
"fmt"
)

func main() {
p := model.NewPerson("smith")
p.SetAge(18)
p.Setsal(5000)
fmt.Println(p)
fmt.Println(p.Name, "age=", p.GetAge(), "sal=", p.GetSal())
}

/*
&{smith 18 5000}
smith age= 18 sal= 5000
*/

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!