Golang 面向对象编程
Posted 知其黑、受其白
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Golang 面向对象编程相关的知识,希望对你有一定的参考价值。
阅读目录
Golang 面向对象编程1
1 struct 声明和定义
1、Go中面向对象是通过 struct 来实现的,struct 是用户自定义的类型。
type User struct
Username string
Sex string
Age int
AvatarUrl string
注意:type 是用来定义一种类型。
struct 初始化方法 1
var user User
user.Age = 18
user.Username = "user01"
user.Sex = "男"
user.AvatarUrl = "http://my.com/xxx.png"
注意:使用变量名+‘.’+字段名访问结构体中的字段。
package main
import "fmt"
type User struct
Username string
Sex string
Age int
AvatarUrl string
func main()
var user User
user.Age = 18
user.Username = "user01"
user.Sex = "男"
user.AvatarUrl = "http://my.com/xxx.png"
fmt.Printf("user.username=%s age=%d sex%s avatar=%s\\n", user.Username, user.Age, user.Sex, user.AvatarUrl)
PS E:\\TEXT\\test_go\\one> go run .\\test1.go
user.username=user01 age=18 sex男 avatar=http://my.com/xxx.png
PS E:\\TEXT\\test_go\\one>
struct 初始化方法 2
package main
import "fmt"
type User struct
Username string
Sex string
Age int
AvatarUrl string
func main()
// 注意也可以部分初始化
var user User = User
Username: "user01",
Sex: "男",
Age: 18,
AvatarUrl: "http://my.com/xxx.png",
fmt.Printf("user.username=%s age=%d sex%s avatar=%s\\n", user.Username, user.Age, user.Sex, user.AvatarUrl)
// 更简单的写法
user1 := User
Username: "user01",
// 未初始化的字段就是默认值空或零
// Sex: "男",
// Age: 18,
AvatarUrl: "http://my.com/xxx.png",
fmt.Println(user1)
PS E:\\TEXT\\test_go\\one> go run .\\test1.go
user.username=user01 age=18 sex男 avatar=http://my.com/xxx.png
user01 0 http://my.com/xxx.png
PS E:\\TEXT\\test_go\\one>
未初始化的结构体:
var user3 User
fmt.Printf("user3=%#v\\n", user3)
PS E:\\TEXT\\test_go\\one> go run .\\test1.go
user3=main.UserUsername:"", Sex:"", Age:0, AvatarUrl:""
PS E:\\TEXT\\test_go\\one>
结构体类型指针
package main
import "fmt"
type User struct
Username string
Sex string
Age int
AvatarUrl string
func main()
// 结构体类型指针
var user *User = &User
fmt.Printf("%p %#v\\n", user, user)
PS E:\\TEXT\\test_go\\one> go run .\\test1.go
0xc000026080 &main.UserUsername:"", Sex:"", Age:0, AvatarUrl:""
PS E:\\TEXT\\test_go\\one>
注意:&User 和 new(User)
本质上是一样的,都是返回一个结构体的地址。
package main
import "fmt"
type User struct
Username string
Sex string
Age int
AvatarUrl string
func main()
// 结构体类型指针
// var user *User = &User
// fmt.Printf("%p %#v\\n", user, user)
// 0xc000026080 &main.UserUsername:"", Sex:"", Age:0, AvatarUrl:""
var user *User = &User
Username: "user01",
Sex: "男",
AvatarUrl: "http://my.com/xxx.png",
// 这种写法是 go 的语法糖
user.Age = 18
// 相当于 go 内部的这种写法
(*user).Username = "user001"
fmt.Printf("user01=%#v\\n", user)
// user01=&main.UserUsername:"user001", Sex:"男", Age:18, AvatarUrl:"http://my.com/xxx.png"
test()
func test()
var user1 *User = new(User)
user1.Age = 18
fmt.Println(user1)
// & 18
2 struct 的内存布局及构造函数
结构体内存布局:占用一段连续的内存空间。
package main
import "fmt"
type Test struct
A int32
B int32
C int32
D int32
func main()
var t Test
fmt.Printf("a addr:%p\\n", &t.A)
fmt.Printf("b addr:%p\\n", &t.B)
fmt.Printf("c addr:%p\\n", &t.C)
fmt.Printf("d addr:%p\\n", &t.D)
一个字符占四个字节,地址是16进制所以打印出的结果是连续的。
PS E:\\TEXT\\test_go\\one> go run .\\test1.go
a addr:0xc00000e0d0
b addr:0xc00000e0d4
c addr:0xc00000e0d8
d addr:0xc00000e0dc
PS E:\\TEXT\\test_go\\one>
结构体没有构造函数,必要时需要自己实现
自定义包:E:\\TEXT\\test_go\\one\\user\\user.go
package user
type User struct
Username string
Sex string
Age int
AvatarUrl string
自定义执行文件:E:\\TEXT\\test_go\\one\\user_test\\test.go
package main
import (
"fmt"
"one/user"
)
func main()
// 使用第三方类型定义了一个变量
var users user.User
users.Age = 33
fmt.Printf("user=%#v\\n", users)
PS E:\\TEXT\\test_go\\one\\user_test> go run .\\test.go
user=user.UserUsername:"", Sex:"", Age:33, AvatarUrl:""
PS E:\\TEXT\\test_go\\one\\user_test>
编写构造函数:
E:\\TEXT\\test_go\\one\\user\\user.go
package user
type User struct
Username string
Sex string
Age int
AvatarUrl string
// 构造函数
func NewUser(username string, sex string, age int, avatar string) *User
// 第一种方式
// user := &User
// Username: username,
// Sex: sex,
// Age: age,
// AvatarUrl: avatar,
//
user := new(User)
user.Username = username
user.Sex = sex
user.Age = age
user.AvatarUrl = avatar
return user
初始化构造函数:
E:\\TEXT\\test_go\\one\\user_test\\test.go
package main
import (
"fmt"
"one/user"
)
func main()
u := user.NewUser("user01", "女", 33, "xx.jpg")
fmt.Printf("user=%#v\\n", u)
PS E:\\TEXT\\test_go\\one\\user_test> go run .\\test.go
user=&user.UserUsername:"user01", Sex:"女", Age:33, AvatarUrl:"xx.jpg"
PS E:\\TEXT\\test_go\\one\\user_test>
匿名字段和嵌套
匿名字段:即没有名字的字段。
注意:匿名字段默认采用类型名作为字段名。
package main
import "fmt"
type User struct
Username string
Sex string
Age int
AvatarUrl string
int
string
func main()
var user User
user.Username = "user001"
user.Sex = "nv"
user.int = 100
user.string = "hello"
fmt.Printf("user=%#v\\n", user)
PS E:\\TEXT\\test_go\\one> go run .\\test1.go
user=main.UserUsername:"user001", Sex:"nv", Age:0, AvatarUrl:"", int:100, string:"hello"
PS E:\\TEXT\\test_go\\one>
3 匿名字段和 struct 嵌套
package main
import "fmt"
type Address struct
Province string
City string
type User struct
Username string
Sex string
address Address
func main()
user := &User
Username: "user01",
Sex: "nv",
address: Address
Province: "beijing",
City: "beijing",
,
fmt.Printf("user=%#v\\n", user)
PS E:\\TEXT\\test_go\\one> go run .\\test1.go
user=&main.UserUsername:"user01", Sex:"nv", address:main.AddressProvince:"beijing", City:"beijing"
PS E:\\TEXT\\test_go\\one>
指针方式
package main
import "fmt"
type Address struct
Province string
City string
type User struct
Username string
Sex string
address *Address
func main()
user := &User
Username: "user01",
Sex: "nv",
address: &Address
Province: "beijing",
City: "beijing",
,
fmt.Printf("user=%#v\\n", user)
匿名结构体
package main
import "fmt"
type Address struct
Province string
City string
type User struct
Username string
Sex string
*Address
func main()
var user User
user.Username = "user0011"
user.Sex = "nv"
// 第一种方式
user.Address = &Address
Province: "bj",
City: "chengshi",
// 第二种方式
user.Province = "上海"
user.City = "shanghai"
// user 结构体中没有city去匿名结构体找city
fmt.Printf("user=%#v addr=%#v city:%s\\n", user, user.Address, user.City)
PS E:\\TEXT\\test_go\\one> go run .\\test1.go
user=main.UserUsername:"user0011", Sex:"nv", Address:(*main.Address)(0xc0000523c0) addr=&main.AddressProvince:"上海", City:"shanghai"
PS E:\\TEXT\\test_go\\one>
匿名结构体冲突解决
冲突指定字段的名字即可解决。
package main
import "fmt"
type Address struct
Province string
City string
type User struct
Username string
Sex string
City string
*Address
func main()
var user User
user.Username = "user001"
user.Sex = "nv"
user.City = "beijing"
fmt.Printf("user=%#v\\n", user)
user.Address = new(Address)
user.Address.City = "上海"
fmt.Printf("user=%#v city of address:%s\\n", user, user.Address.City)
PS E:\\TEXT\\test_go\\one> go run .\\test1.go
user=main.UserUsername:"user001", Sex:"nv", City:"beijing", Address:(*main.Address)(nil)
user=main.UserUsername:"user001", Sex:"nv", City:"beijing", Address:(*main.Address)(0xc0000523e0) city of address:上海
PS E:\\TEXT\\test_go\\one
package main
import "fmt"
type Address struct
Province string
City string
CreateTime string
type Email struct
Account string
CreateTime string
type User struct
Username string
Sex string
City string
*Address
*Email
func main()
var user User
user.Username = "user001"
user.Sex = "nv"
user.City = "beijing"
user.Address = new(Address)
user.Email = new(Email)
user.Address.City = "上海"
user.Email.CreateTime = "email_createtime"
fmt.Printf("user=%#v createtime:%s\\n", user, user.Email.CreateTime)
PS E:\\TEXT\\test_go\\one> go run .\\test1.go
user=main.UserUsername:"user001", Sex:"nv", City:"beijing", Address:(*main.Address)(0xc0001004b0), Email:(*main.Email)(0xc0000523c0) createtime:email_createtime
PS E:\\TEXT\\test_go\\one>
4 struct 与 tag 应用
字段可见性,大写表示可公开访问,小写表示私有。
tag 是结构体的元信息,可以在运行的时候通过反射机制读取出来
字段类型后面,以反引号括起来的 key-value 结构的字符串,多个tag已逗号隔开。
package main
import (
"encoding/json"
"fmt"
)
// 双引号表示 value
type User struct
Username string `json:"username",db:"user_name"`
Sex string `json:"sex"`
Age int `json:"age"`
avatarUrl string
CreateTime string
func main()
user := &User
Username: "user001",
Sex: "女",
Age: 33,
avatarUrl: "https://my.com/xx.png",
CreateTime: "2022-30-51",
// json 序列化后是json格式,返回的是字符切片
data, _ := json.Marshal(user)
fmt.Printf("json str:%s\\n", string(data))
PS E:\\TEXT\\test_go\\one> go run .\\test1.go
json str:"username":"user001","sex":"女","age":33,"CreateTime":"2022-30-51"
PS E:\\TEXT\\test_go\\one>
5 函数方式实现一个简单的学生管理系统
实现一个简单的学生管理系统,每个学生有分数、年级、性别、名字等字段,用户可以在控制台添加学生、修改学生信息、打印所有学生列表的功能。
E:\\TEXT\\test_go\\one\\test1.go
package main
import (
"fmt"
"one/student"
"os"
)
var (
AllStudents []*student.Student
)
func showMenu()
fmt.Println("1、add student")
fmt.Println("2、modify student")
fmt.Println("3、show all student")
fmt.Println("4、exited\\n\\n")
func inputStudent() *student.Student
var (
username string
sex int
grade string
score float32
)
fmt.Println("please input username:")
fmt.Scanf("%s\\n", &username)
fmt.Println("please input sex:[0|1]")
fmt.Scanf("%d\\n", &sex)
fmt.Println("please input grade:[0-6]")
fmt.Scanf("%s\\n", &grade)
fmt.Println("please input score:[0|100]")
fmt.Scanf("%f\\n", &score)
stu := student.NewStudent(username, sex, score, grade)
return stu
func AddStudent()
stu := inputStudent()
for index, v := range AllStudents
if v.Username == stu.Username
fmt.Printf("user %s success update\\n\\n", stu.Username)
AllStudents[index] = stu
return
AllStudents = append(AllStudents, stu)
fmt.Printf("user %s success insert\\n", stu.Username)
func ModifyStudent()
stu := inputStudent()
for index, v := range AllStudents
if v.Username == stu.Username
AllStudents[index] = stu
fmt.Printf("user %s success update\\n\\n", stu.Username)
return
fmt.Printf("user %s is not fund\\n", stu.Username)
func ShowAllStudent()
for _, v := range AllStudents
fmt.Printf("user:%s info:%#v\\n", v.Username, v)
func main()
for
showMenu()
var sel int
fmt.Scanf("%d\\n", &sel)
switch sel
case 1:
AddStudent()
case 2:
ModifyStudent()
case 3:
ShowAllStudent()
case 4:
os.Exit(0)
PS E:\\TEXT\\test_go\\one> go run .\\test1.go
1、add student
2、modify student
3、show all student
4、exited
1
please input username:
wgchen
please input sex:[0|1]
1
please input grade:[0-6]
5
please input score:[0|100]
99
user wgchen success insert
1、add student
2、modify student
3、show all student
4、exited
1
please input username:
xiaojun
please input sex:[0|1]
1
please input grade:[0-6]
1
please input score:[0|100]
88
user xiaojun success insert
1、add student
2、modify student
3、show all student
4、exited
1
please input username:
ycc
please input sex:[0|1]
0
please input grade:[0-6]
6
please input score:[0|100]
100
user ycc success insert
1、add student
2、modify student
3、show all student
4、exited
3
user:wgchen info:&student.StudentUsername:"wgchen", Score:99, Grade:"5", Sex:1
user:xiaojun info:&student.StudentUsername:"xiaojun", Score:88, Grade:"1", Sex:1
user:ycc info:&student.StudentUsername:"ycc", Score:100, Grade:"6", Sex:0
1、add student
2、modify student
3、show all student
4、exited
4
PS E:\\TEXT\\test_go\\one>
E:\\TEXT\\test_go\\one\\student\\student.go
package student
type Student struct
Username string
Score float32
Grade string
Sex int
func NewStudent(username string, sex int, score float32, grade string) (stu *Student)
stu = &Student
Username: username,
Sex: sex,
Score: score,
Grade: grade,
return
Golang 面向对象编程2
函数不属于任何类型,方法属于特定的类型。
1 方法的定义
Go的方法采用另外一种方式实现。
Go 的方法是在函数前面加上一个接受者,这样编译器就知道这个方法属于哪个类型了。
package main
import "fmt"
// struct 值类型
type People struct
Name string
Country string
func (p People) Print()
fmt.Printf("name=%s country=%s\\n", p.Name, p.Country)
func (p People) Set(name string, country string)
p.Name = name
p.Country = country
func main()
// p1 值拷贝
var p1 People = People
Name: "people01",
Country: "china",
p1.Print()
// 这样是修改不了结构本身的值的,因为是值拷贝
p1.Set("peple_set", "shanghai")
PS E:\\TEXT\\test_go\\one> go run .\\main.go
name=people01 country=china
PS E:\\TEXT\\test_go\\one>
可以为当前包内定义的任何类型增加方法。
package main
import "fmt"
type Integer int
func (i Integer) Print()
fmt.以上是关于Golang 面向对象编程的主要内容,如果未能解决你的问题,请参考以下文章