1763 字
9 分钟
Go 语言学习笔记 -第16章
Go 语言学习笔记 -第16章
结构体
封装
model/model.go
package model
import "fmt"
//结构体开头首字母小写type person struct { Name string age int //变量小写其他包不能直接访问 sal float64}
//写一个工厂函数,相当于构造函数func NewPerson(name string) *person { return &person{ Name: name, }}
//为了访问sage, salary编写一对get/set方法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}main/main.go
package main
import ( "fmt" "prj/model")
func main() { p := model.NewPerson("smith") p.SetAge(18) p.SetSal(5000)
fmt.Println(p.Name, "age=", p.GetAge(), "sal=", p.GetSal())
}继承
1.普通方法
package main
import ( "fmt")
//小学生type Pupil struct { Name string Age int Score int}
func (p *Pupil) ShowInfo() { fmt.Printf("学生名=%v 年龄=%v 成绩=%v\n", p.Name, p.Age, p.Score)}
func (p *Pupil) SetScore(score int) { p.Score = score}
func (p *Pupil) testing() { fmt.Println("小学生正在考试...")}
//大学生
//研究生
func main() { //测试 var pupil = &Pupil{ Name: "tom", Age: 10, }
pupil.testing() pupil.SetScore(90) pupil.ShowInfo()}2.继承写法
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 //嵌入Student匿名结构体}
func (p *Pupil) testing() { fmt.Println("小学生正在考试...")}
//大学生type Graduate struct { Student}
func (p *Graduate) testing() { fmt.Println("大学生正在考试...")}
//研究生
func main() { //测试 var pupil = &Pupil{} pupil.Student.Name = "tom" pupil.Student.Age = 10
pupil.testing() pupil.Student.SetScore(90) pupil.Student.ShowInfo()
var graduate = &Graduate{} graduate.Student.Name = "Mary" graduate.Student.Age = 20
graduate.testing() graduate.Student.SetScore(60) graduate.Student.ShowInfo()}注意事项:
事项1:
package main
import ( "fmt")
type A struct { Name string age int //小写也是可以继承的}
func (a *A) SayOk() { fmt.Println("A sayok")}
func (a *A) hello() { fmt.Println("A hello")}
type B struct { A}
func main() { var b B // b.A.Name = "tom" //也可以写成b.Name = "tom" // b.A.age = 19 //也可以写成b.age = 19
b.Name = "Smith" b.age = 10
b.SayOk() b.hello()
// b.A.SayOk() //也可以写成b.SayOk() // b.A.hello()//也可以写成b.hello()}事项2:
package main
import ( "fmt")
type A struct { Name string age int //小写也是可以继承的}
func (a *A) SayOk() { fmt.Println("A sayok", a.Name)}
func (a *A) hello() { fmt.Println("A hello", a.Name)}
type B struct { A Name string //相同字段就近原则}
func (b *B) SayOk() { fmt.Println("B sayok", b.Name)}
func main() { var b B
b.Name = "Smith" b.A.Name = "jack"
b.SayOk() //B sayok Smith b.hello() //A hello
}事项3:
package main
import "fmt"
type A struct { Name string age int}
type B struct { Name string age int}
type C struct { A B Name string}
func main() { var c C c.Name = "tom" //?
//如果C没有Name字段,而A和B有Name,则要指定匿名结构体来区分 //c.Name ==> c.A.Name, 这个规则对方法也是一样的
fmt.Println("c=", c)
}事项4:
package main
import "fmt"
type A struct { Name string age int}
type B struct { Name string age int}
type C struct { A B}
type D struct { a A //有名结构体 组合关系 // Name string}
func main() { var d D // d.Name = "jack" //报错,需要写成d.a.Name
//如果D是一个有名结构体,访问要带上有名结构体的名字 //需要写成d.a.Name
d.a.Name = "jack" fmt.Println("d=", d)
}事项5:
package main
import "fmt"
type Goods struct { Name string Price float64}
type Brand struct { Name string Address string}
type TV struct { Goods Brand}
type TV2 struct { *Goods *Brand}
func main() {
tv := TV{Goods{"电视机001", 5000.99}, Brand{"海尔", "山东"}} // tv := TV{ // Goods{ // Name: "电视机001", // Price: 5000.99, // }, // Brand{ // Name: "海尔", // Address: "山东", // }, // }
tv2 := TV2{&Goods{"电视机002", 9999.99}, &Brand{"创维", "河南"}} fmt.Println("tv=", tv) fmt.Println("tv2=", *tv2.Goods, *tv2.Brand)
}事项6:
package main
import "fmt"
type Goods struct { Name string Price float64}
type TV struct { Goods int //匿名字段 // int n int}
func main() {
var tv TV tv.Name = "aaa" tv.Price = 100 tv.int = 20 tv.n = 40
fmt.Println("tv=", tv)}多态
package main
import ( "fmt")
//Usb 声明//接口体现多态、高内聚低耦合思想type Usb interface { //声明两个没有实现的方法//根据方法来判断 Start() Stop()}
//手机type Phone struct {}
//让Phone实现Usb接口的方法func (p Phone) Start() { fmt.Println("手机开始工作...")}func (p Phone) Stop() { fmt.Println("手机停止工作...")}
//照相机type Camera struct {}
//让Camera实现Usb接口的方法func (c Camera) Start() { fmt.Println("相机开始工作...")}func (c Camera) Stop() { fmt.Println("相机停止工作...")}
//计算机type Computer struct {}
//编写working方法,接收一个Usb接口类型变量//只要是实现了Usb接口: 就是实现了Usb接口声明所有方法func (c Computer) Working(usb Usb) { usb.Start() usb.Stop()
}func main() {
computer := Computer{} phone := Phone{} // camera = Camera{}
computer.Working(phone)
}说明:
这里的Usb usb,既可以接收手机变量、又可以接收相机变量,就体现了Usb接口多态特性
接口体现多态特征
1、多态参数 如Usb usb
2、多态数组
package main
import ( "fmt")
//Usb 声明//接口体现多态、高内聚低耦合思想type Usb interface { //声明两个没有实现的方法 //根据方法来判断 Start() Stop()}
//手机type Phone struct { name string}
//让Phone实现Usb接口的方法func (p Phone) Start() { fmt.Println("手机开始工作...")}func (p Phone) Stop() { fmt.Println("手机停止工作...")}
//照相机type Camera struct { name string}
//让Camera实现Usb接口的方法func (c Camera) Start() { fmt.Println("相机开始工作...")}func (c Camera) Stop() { fmt.Println("相机停止工作...")}
func main() {
//定义usb接口数组,多态数组 var usbArr [3]Usb usbArr[0] = Phone{"vivo"} usbArr[1] = Phone{"小米"} usbArr[2] = Camera{"尼康"}
fmt.Println(usbArr)
}golang接口和继承的关系
package main
import "fmt"
type Monkey struct { Name string}
type LittleMonkey struct { Monkey}
//声明接口type BirdAble interface { Flying()}
type FishAble interface { Swimming()}
func (this *Monkey) climbing() { fmt.Println(this.Name, "生来会爬树...")}
//让littleMoney实现BirdAblefunc (this *LittleMonkey) Flying() { fmt.Println(this.Name, "通过学习会飞翔...")}
func (this *LittleMonkey) Swimming() { fmt.Println(this.Name, "通过学习会游泳...")}
func main() {
monkey := LittleMonkey{ Monkey{ Name: "悟空", }, }
monkey.climbing() monkey.Flying() monkey.Swimming()
}总结:
1.当A结构体继承了B结构体,那么A结构体自动继承了B结构体的字段和方法,并且可以直接使用
2.当A结构体需要扩展功能,同时不希望区破坏继承关系,则可以去实现某个接口,因此我们可以认为,实现接口是对继承机制的补充
3.接口和继承解决的问题不同 1)继承的价值主要在于:解决代码的复用性和可维护性 2)接口的价值主要在于:设计,设计好各种规范(方法),让其他自定义类型去实现这些方法
4.接口比继承更加灵活 继承是满足 is -a的关系 Person- Student 接口只需满足 like -a的关系 BirdAble LittleMoney
5.接口在一定程度上实现代码解耦
Go 语言学习笔记 -第16章
https://blog.zhequtao.com/posts/golang/go-learning/学习笔记-go/第16章/