当前位置 首页> 常识>

封装是什么意思要完成什么操作(面向对象—封装)

时间:2024-12-11 10:56:50

创建结构体实例时指定字段值

【1】方式1:按照顺序赋值操作

缺点:必须按照顺序有局限性

【2】方式2:按照指定类型

【3】方式3:想要返回结构体的指针类型

package main

import "fmt"
type Student struct{
	Name string
	Age int
}

func main()  {
	// 方式1:按照顺序赋值操作
	var s1 Student = Student{"菜园子",15}
	fmt.Println(s1)

	// 方式2:按照指定类型
	var s2 Student = Student{
		Name: "菜先生",
		Age: 30,
	}
	fmt.Println(s2)

	// 方式3:想要返回结构体的指针类型
	var s3 *Student = &Student{"菜女神",39}
	fmt.Println(*s3)

	var s4 *Student = &Student{
		Name: "菜小姐",
		Age: 39,
	}
	fmt.Println(*s4)
}

跨包创建结构体实例

【1】创建不同的包:


【2】student.go:

package model

type Student struct{
	Name string
	Age int
}

【3】main.go:


package main

import (
	"fmt"
	"gocode/testproject01/unit10/demo13/model"
)
func main()  {
	// 跨包创建结构体Student实例
	// var s = model.Student{
	// 	Name: "菜园子",
	// 	Age: 18,
	// }
	s := model.Student{"菜园子",10}
	fmt.Println(s)
}

发现:如果结构体首字母大写的话,在其它包下可以访问

但是:如果结构体的首字母小写?


解决:结构体首字母小写,跨包访问没问题:---》工厂模式

package model

// type Student struct{
// 	Name string
// 	Age int
// }

type student struct{
	Name string
	Age int
}

func NewStudent(n string, a int) * student{
	return &student{n,a}
}
package main

import (
	"fmt"
	"gocode/testproject01/unit10/demo13/model"
)
func main()  {
	// 跨包创建结构体Student实例
	// var s = model.Student{
	// 	Name: "菜园子",
	// 	Age: 18,
	// }
	// s := model.Student{"菜园子",10}
	// fmt.Println(s)
	s := model.NewStudent("菜女神",12)
	fmt.Println(*s)
}

封装

【1】什么是封装:

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

【2】封装的好处:

1) 隐藏实现细节

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

【3】Golang中如何实现封装:

1) 建议将结构体、字段(属性)的首字母小写(其它包不能使用,类似private,实际开发不小写也可能,因为封装没有那么严格)

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

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

func (var 结构体类型名)SetXxx(参数列表){

//加入数据验证的业务逻辑

var.Age =参数

}

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

func (var结构体类型名) GetXxx() (返回值列表){

return var.字段;

}

【4】代码实现:


package model
import "fmt"
type person struct{
	Name string
	age int //其它包不能直接访问
} 

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

// 定义set和get方法,对age字段进行封装,因为在方法中可以加一系列的限制操作,确保被封装字段的安全合理性
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
}
package main

import (
	"fmt"
	"gocode/testproject01/unit10/demo14/model"
)
func main()  {
	p := model.NewPerson("菜园子")
	p.SetAge(29)

	fmt.Println(p.Name)
	// fmt.Println(p.age)
	fmt.Println(p.GetAge())
	fmt.Println(*p)
}