go仍然有面向对象编程的继、封装、多态的特性,只是实现方式和其他 OOP语言不同。Go 通过接口(interface)和结构体(struct)来实现这些特性
封装就是把抽象出来的字段和对字段的操作封装在一起,数据被保护在内,程序的其他包只能通过被授权的操作(方法)才能对字段进行操作
封装的好处
-
封装可以隐藏实现的细节
-
封装也可以对数据进行验证,保证数据的正确性
封装的实现
对结构体的属性进行封装
通过方法、包实现封装
-
1、将结构体和结构体中的字段首字母小写,使其成为包内可见的私有字段
-
2、使用工厂模式来创建结构体实例,工厂函数的首字母大写,使其成为包外可见的公共函数
-
3、提供公有方法(例如 SetXxxx GetXxxx 方法)来访问和修改这些私有字段,这些方法的首字母大写,使其成为包外可见的公共方法。SetXxxx 方法可以对输入的数据进行验证,保证数据的正确性
封装的示例
- 在model 包中定义一个结构体 person,并对其字段进行封装
package model
import (
"fmt"
)
// 定义一个结构体 person
type person struct {
name string // 私有字段
age int // 私有字段
}
func NewPerson() *person {
return &person{}
}
// 定义公有方法 SetName 来设置 name 字段的值,并进行验证
func (p *person) SetName(name string) {
if len(name) == 0 {
fmt.Println("name cannot be empty")
return
}
p.name = name
}
// 定义公有方法 GetName 来获取 name 字段的值
func (p *person) GetName() string {
return p.name
}
// 定义公有方法 SetAge 来设置 age 字段的值,并进行验证
func (p *person) SetAge(age int) {
if age < 0 {
fmt.Println("age cannot be negative")
return
}
p.age = age
}
// 定义公有方法 GetAge 来获取 age 字段的值
func (p *person) GetAge() int {
return p.age
}
- 在 main 包中使用 model 包中的 person 结构体
package main
import (
"fmt"
"model"
)
func main() {
// 创建 person 实例
p := model.NewPerson()
// 设置 person 的 name 和 age 字段的值
p.SetName("Alice")
p.SetAge(30)
// 获取 person 的 name 和 age 字段的值
fmt.Println("Name:", p.GetName())
fmt.Println("Age:", p.GetAge())
}