Golang第五章:结构体和对象
作者:互联网
Golang面向对象
1. Golang没有类,Go的结构体相对于其它编程语言的类
2. Golang去掉了传统OOP语言的继承、方法重载、构造函数和析构函数、隐藏的指针等等
3. Golang仍有面向对象编程的继承、封装和多态的特性,只是实现方式不同
创建结构体实例的四种方法
type Cat struct { Name string Age int Color string } func main() { // 结构体实例创建方式1 var cat1 Cat cat1.Name = "小白" // 方式2 cat2 := Cat{"haha", 13, "红"} fmt.Println(cat2) fmt.Println(cat1) // 方式3 var cat3 *Cat = new(Cat) (*cat3).Name = "小花" // 以上也可以写成cat3.Name = "小花" // 原因:go的设计者为了程序员使用方便,底层会对以上语句进行处理,会转化成(*cat3) // 方式4 // 下面的语句,也可以直接给字段赋值 // var cat4 *Cat = &Cat{"haha", 321, "绿"} var cat4 *Cat = &Cat{} (*cat4).Name = "小曹" // 以上也可以写成cat3.Name = "小花" // 原因:go的设计者为了程序员使用方便,底层会对以上语句进行处理,会转化成(*cat3) fmt.Println(*cat4) fmt.Println(*cat3) fmt.Println(cat2) fmt.Println(cat1) }
结构体的注意事项
1. 结构体的所有字段在内存中是连续的
2. 对一个结构体进行type重新定义,Golang认为是新的数据类型,但相互间可以强转
3. 结构体的每个字段上,可以写上一个tag,该tag可以通过反射机制获取,常见的使用场景就是序列化和反序列化
4. 如果一个变量实现了String()方法,那么fmt.Println默认会调用这个变量的String()进行输出——该功能与java的toString()一致
5. 不管调用形式如何,真正决定是值拷贝还是地址拷贝,看这个方法是和哪个类型绑定——如func (cat *Cat)为地址拷贝,func (cat Cat)为值拷贝
结构体序列化
import ( "fmt" "encoding/json" ) type Cat struct { Name string `json: "name"` Age int `json:"age"` Color string `json:"skill"` } func main() { // 方式2 cat2 := Cat{"haha", 13, "红"} jsonStr, err := json.Marshal(cat2) if err != nil { fmt.Println("json 处理错误", err) } fmt.Println("jsonStr", string(jsonStr)) }
结构体绑定方法
创建结构体实例指定字段值
工厂模式
package main import ( "fmt" "go_code/project05/factory/model" ) func main() { var str = model.NewStudent("tom~", 89.2) fmt.Println(str) fmt.Println("score:", str.GetScore()) } package model //定义一个结构体 type student struct { Name string score float64 } func NewStudent(n string, s float64) *student { return &student { Name: n, score: s, } } func (s *student)GetScore() (float64) { return s.score }
继承
结构体可以使用嵌套结构体所有的方法和字段,无论首字母大小写
package main import ( "fmt" ) // 学生 type Student struct { Name string Age int Score int } func (stu *Student) showInfo() { fmt.Printf("学生名=%v 年龄=%v 成绩=%v\n", stu.Name, stu.Age, stu.Score) } func (stu *Student) SetScore(score int) { stu.Score = score } // 小学生 type Pupil struct { Student } func (p *Pupil) Testing() { fmt.Println("小学生在考试") } func main() { pupil := &Pupil{} pupil.Student.Name = "tom~" pupil.Student.Age = 8 pupil.Testing() pupil.SetScore(25) pupil.showInfo() }
接口
// 声明一个接口 type Usb interface { Start() Stop() } type Phone struct { } func (p Phone) Start() { fmt.Println("phone start") } func (p Phone) Stop() { fmt.Println("phone bomb") } type Computer struct { } func (c Computer) Working(usb Usb) { usb.Start() usb.Stop() } func main() { computer := Computer{} phone := Phone{} computer.Working(phone) // 输出phone start、phone bomb }
一个自定义类型(不止是结构体)只有实现了某个接口,才能将自定义类型的实例(变量)赋给接口类型
// 声明一个接口 type Usb interface { Start() } type Phone struct { } type integer int func (i integer) Start() { fmt.Println("integer Start") } func (p Phone) Start() { fmt.Println("phone start") } func main() { var phone Phone var usb Usb = phone usb.Start() var i integer var usb2 Usb = i usb2.Start() }
类型断言
类型断言(Type Assertion)是一个使用在接口值上的操作,用于检查接口类型变量所持有的值是否实现了期望的接口或者具体的类型。
type Point struct { x int y int } func main() { var a interface{} var point Point = Point{1, 2} a = point var b Point b, ok := a.(Point) if ok { fmt.Println("convert success") } else { fmt.Println("convert failed") } fmt.Println(b) }
标签:对象,fmt,Cat,Golang,var,第五章,func,Println,type 来源: https://www.cnblogs.com/tianshu/p/16209235.html