Golang 【第十一篇】面向对象(下)
Golang 【第十一篇】面向对象(下)
1 抽象

package main import ( "fmt" ) //定义一个结构体Account type Account struct { AccountNo string Pwd string Balance float64 } //方法 //1. 存款 func (account *Account) Deposite(money float64, pwd string) { //看下输入的密码是否正确 if pwd != account.Pwd { fmt.Println("你输入的密码不正确") return } //看看存款金额是否正确 if money <= 0 { fmt.Println("你输入的金额不正确") return } account.Balance += money fmt.Println("存款成功~~") } //取款 func (account *Account) WithDraw(money float64, pwd string) { //看下输入的密码是否正确 if pwd != account.Pwd { fmt.Println("你输入的密码不正确") return } //看看取款金额是否正确 if money <= 0 || money > account.Balance { fmt.Println("你输入的金额不正确") return } account.Balance -= money fmt.Println("取款成功~~") } //查询余额 func (account *Account) Query(pwd string) { //看下输入的密码是否正确 if pwd != account.Pwd { fmt.Println("你输入的密码不正确") return } fmt.Printf("你的账号为=%v 余额=%v \n", account.AccountNo, account.Balance) } func main() { //测试一把 account := Account{ AccountNo : "gs1111111", Pwd : "666666", Balance : 100.0, } //这里可以做的更加灵活,就是让用户通过控制台来输入命令... //菜单.... account.Query("666666") account.Deposite(200.0, "666666") account.Query("666666") account.WithDraw(150.0, "666666") account.Query("666666") }
2 封装

package model import "fmt" type person struct { Name string age int //其它包不能直接访问.. sal float64 } //写一个工厂模式的函数,相当于构造函数 func NewPerson(name string) *person { return &person{ Name : name, } } //为了访问age 和 sal 我们编写一对SetXxx的方法和GetXxx的方法 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 }

package main import ( "fmt" "go_code/chapter11/encapsulate/model" ) func main() { p := model.NewPerson("smith") p.SetAge(18) p.SetSal(5000) fmt.Println(p) fmt.Println(p.Name, " age =", p.GetAge(), " sal = ", p.GetSal()) }
encapsulate_exercise

package model import ( "fmt" ) //定义一个结构体account type account struct { accountNo string pwd string balance float64 } //工厂模式的函数-构造函数 func NewAccount(accountNo string, pwd string, balance float64) *account { if len(accountNo) < 6 || len(accountNo) > 10 { fmt.Println("账号的长度不对...") return nil } if len(pwd) != 6 { fmt.Println("密码的长度不对...") return nil } if balance < 20 { fmt.Println("余额数目不对...") return nil } return &account{ accountNo : accountNo, pwd : pwd, balance : balance, } } //方法 //1. 存款 func (account *account) Deposite(money float64, pwd string) { //看下输入的密码是否正确 if pwd != account.pwd { fmt.Println("你输入的密码不正确") return } //看看存款金额是否正确 if money <= 0 { fmt.Println("你输入的金额不正确") return } account.balance += money fmt.Println("存款成功~~") } //取款 func (account *account) WithDraw(money float64, pwd string) { //看下输入的密码是否正确 if pwd != account.pwd { fmt.Println("你输入的密码不正确") return } //看看取款金额是否正确 if money <= 0 || money > account.balance { fmt.Println("你输入的金额不正确") return } account.balance -= money fmt.Println("取款成功~~") } //查询余额 func (account *account) Query(pwd string) { //看下输入的密码是否正确 if pwd != account.pwd { fmt.Println("你输入的密码不正确") return } fmt.Printf("你的账号为=%v 余额=%v \n", account.accountNo, account.balance) }

package main import ( "fmt" "go_code/chapter11/encapexercise/model" ) func main() { //创建一个account变量 account := model.NewAccount("jzh11111", "000", 40) if account != nil { fmt.Println("创建成功=", account) } else { fmt.Println("创建失败") } }
3 继承

package main import ( "fmt" ) //编写一个学生考试系统 type Student struct { Name string Age int Score int } //将Pupil 和 Graduate 共有的方法也绑定到 *Student 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 } //给 *Student 增加一个方法,那么 Pupil 和 Graduate都可以使用该方法 func (stu *Student) GetSum(n1 int, n2 int) int { return n1 + n2 } //小学生 type Pupil struct { Student //嵌入了Student匿名结构体 } //显示他的成绩 //这时Pupil结构体特有的方法,保留 func (p *Pupil) testing() { fmt.Println("小学生正在考试中.....") } //大学生, 研究生。。 //大学生 type Graduate struct { Student //嵌入了Student匿名结构体 } //显示他的成绩 //这时Graduate结构体特有的方法,保留 func (p *Graduate) testing() { fmt.Println("大学生正在考试中.....") } //代码冗余.. 高中生.... func main() { //当我们对结构体嵌入了匿名结构体使用方法会发生变化 pupil := &Pupil{} pupil.Student.Name = "tom~" pupil.Student.Age = 8 pupil.testing() pupil.Student.SetScore(70) pupil.Student.ShowInfo() fmt.Println("res=", pupil.Student.GetSum(1, 2)) graduate := &Graduate{} graduate.Student.Name = "mary~" graduate.Student.Age = 28 graduate.testing() graduate.Student.SetScore(90) graduate.Student.ShowInfo() fmt.Println("res=", graduate.Student.GetSum(10, 20)) }

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.A.Name = "tom" // b.A.age = 19 // b.A.SayOk() // b.A.hello() // //上面的写法可以简化 // b.Name = "smith" // b.age = 20 // b.SayOk() // b.hello() var b B b.Name = "jack" // ok b.A.Name = "scott" b.age = 100 //ok b.SayOk() // B SayOk jack b.A.SayOk() // A SayOk scott b.hello() // A hello ? "jack" 还是 "scott" }

package main import ( "fmt" ) type A struct { Name string age int } type B struct { Name string Score float64 } type C struct { A B //Name string } type D struct { a A //有名结构体 } type Goods struct { Name string Price float64 } type Brand struct { Name string Address string } type TV struct { Goods Brand } type TV2 struct { *Goods *Brand } type Monster struct { Name string Age int } type E struct { Monster int n int } func main() { var c C //如果c 没有Name字段,而A 和 B有Name, 这时就必须通过指定匿名结构体名字来区分 //所以 c.Name 就会包编译错误, 这个规则对方法也是一样的! c.A.Name = "tom" // error fmt.Println("c") //如果D 中是一个有名结构体,则访问有名结构体的字段时,就必须带上有名结构体的名字 //比如 d.a.Name var d D d.a.Name = "jack" //嵌套匿名结构体后,也可以在创建结构体变量(实例)时,直接指定各个匿名结构体字段的值 tv := TV{ Goods{"电视机001", 5000.99}, Brand{"海尔", "山东"}, } //演示访问Goods的Name fmt.Println(tv.Goods.Name) fmt.Println(tv.Price) tv2 := TV{ Goods{ Price : 5000.99, Name : "电视机002", }, Brand{ Name : "夏普", Address :"北京", }, } fmt.Println("tv", tv) fmt.Println("tv2", tv2) tv3 := TV2{ &Goods{"电视机003", 7000.99}, &Brand{"创维", "河南"}, } tv4 := TV2{ &Goods{ Name : "电视机004", Price : 9000.99, }, &Brand{ Name : "长虹", Address : "四川", }, } fmt.Println("tv3", *tv3.Goods, *tv3.Brand) fmt.Println("tv4", *tv4.Goods, *tv4.Brand) //演示一下匿名字段时基本数据类型的使用 var e E e.Name = "狐狸精" e.Age = 300 e.int = 20 e.n = 40 fmt.Println("e=", e) }
其他:
3.1 匿名字段为基本数据类型
3.2 多重继承
4 接口(interface)

package main import ( "fmt" ) type Stu struct { Name string } func (stu Stu) Say() { fmt.Println("Stu Say()") } type integer int func (i integer) Say() { fmt.Println("integer Say i =" ,i ) } type AInterface interface { Say() } type BInterface interface { Hello() } type Monster struct { } func (m Monster) Hello() { fmt.Println("Monster Hello()~~") } func (m Monster) Say() { fmt.Println("Monster Say()~~") } func main() { var stu Stu //结构体变量,实现了 Say() 实现了 AInterface var a AInterface = stu a.Say() var i integer = 10 var b AInterface = i b.Say() // integer Say i = 10 //Monster实现了AInterface 和 BInterface var monster Monster var a2 AInterface = monster var b2 BInterface = monster a2.Say() b2.Hello() }

package main import ( "fmt" ) type BInterface interface { test01() } type CInterface interface { test02() } type AInterface interface { BInterface CInterface test03() } //如果需要实现AInterface,就需要将BInterface CInterface的方法都实现 type Stu struct { } func (stu Stu) test01() { } func (stu Stu) test02() { } func (stu Stu) test03() { } type T interface{ } func main() { var stu Stu var a AInterface = stu a.test01() var t T = stu //ok fmt.Println(t) var t2 interface{} = stu var num1 float64 = 8.8 t2 = num1 t = num1 fmt.Println(t2, t) }

package main import ( "fmt" "sort" "math/rand" ) //1.声明Hero结构体 type Hero struct{ Name string Age int } //2.声明一个Hero结构体切片类型 type HeroSlice []Hero //3.实现Interface 接口 func (hs HeroSlice) Len() int { return len(hs) } //Less方法就是决定你使用什么标准进行排序 //1. 按Hero的年龄从小到大排序!! func (hs HeroSlice) Less(i, j int) bool { return hs[i].Age < hs[j].Age //修改成对Name排序 //return hs[i].Name < hs[j].Name } func (hs HeroSlice) Swap(i, j int) { //交换 // temp := hs[i] // hs[i] = hs[j] // hs[j] = temp //下面的一句话等价于三句话 hs[i], hs[j] = hs[j], hs[i] } //1.声明Student结构体 type Student struct{ Name string Age int Score float64 } //将Student的切片,安Score从大到小排序!! func main() { //先定义一个数组/切片 var intSlice = []int{0, -1, 10, 7, 90} //要求对 intSlice切片进行排序 //1. 冒泡排序... //2. 也可以使用系统提供的方法 sort.Ints(intSlice) fmt.Println(intSlice) //请大家对结构体切片进行排序 //1. 冒泡排序... //2. 也可以使用系统提供的方法 //测试看看我们是否可以对结构体切片进行排序 var heroes HeroSlice for i := 0; i < 10 ; i++ { hero := Hero{ Name : fmt.Sprintf("英雄|%d", rand.Intn(100)), Age : rand.Intn(100), } //将 hero append到 heroes切片 heroes = append(heroes, hero) } //看看排序前的顺序 for _ , v := range heroes { fmt.Println(v) } //调用sort.Sort sort.Sort(heroes) fmt.Println("-----------排序后------------") //看看排序后的顺序 for _ , v := range heroes { fmt.Println(v) } i := 10 j := 20 i, j = j, i fmt.Println("i=", i, "j=", j) // i=20 j = 10 }

package main import ( "fmt" ) //Monkey结构体 type Monkey struct { Name string } //声明接口 type BirdAble interface { Flying() } type FishAble interface { Swimming() } func (this *Monkey) climbing() { fmt.Println(this.Name, " 生来会爬树..") } //LittleMonkey结构体 type LittleMonkey struct { Monkey //继承 } //让LittleMonkey实现BirdAble func (this *LittleMonkey) Flying() { fmt.Println(this.Name, " 通过学习,会飞翔...") } //让LittleMonkey实现FishAble func (this *LittleMonkey) Swimming() { fmt.Println(this.Name, " 通过学习,会游泳..") } func main() { //创建一个LittleMonkey 实例 monkey := LittleMonkey{ Monkey { Name : "悟空", }, } monkey.climbing() monkey.Flying() monkey.Swimming() }
5 多态

package main import ( "fmt" ) //声明/定义一个接口 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接口数组,可以存放Phone和Camera的结构体变量 //这里就体现出多态数组 var usbArr [3]Usb usbArr[0] = Phone{"vivo"} usbArr[1] = Phone{"小米"} usbArr[2] = Camera{"尼康"} fmt.Println(usbArr) }
6 断言

package main import ( "fmt" ) type Point struct { x int y int } func main() { var a interface{} var point Point = Point{1, 2} a = point //oK // 如何将 a 赋给一个Point变量? var b Point // b = a 不可以 // b = a.(Point) // 可以 b = a.(Point) fmt.Println(b) // //类型断言的其它案例 // var x interface{} // var b2 float32 = 1.1 // x = b2 //空接口,可以接收任意类型 // // x=>float32 [使用类型断言] // y := x.(float32) // fmt.Printf("y 的类型是 %T 值是=%v", y, y) //类型断言(带检测的) var x interface{} var b2 float32 = 2.1 x = b2 //空接口,可以接收任意类型 // x=>float32 [使用类型断言] //类型断言(带检测的) if y, ok := x.(float32); ok { fmt.Println("convert success") fmt.Printf("y 的类型是 %T 值是=%v", y, y) } else { fmt.Println("convert fail") } fmt.Println("继续执行...") }

package main import ( "fmt" ) //声明/定义一个接口 type Usb interface { //声明了两个没有实现的方法 Start() Stop() } type Phone struct { name string } //让Phone 实现 Usb接口的方法 func (p Phone) Start() { fmt.Println("手机开始工作。。。") } func (p Phone) Stop() { fmt.Println("手机停止工作。。。") } func (p Phone) Call() { fmt.Println("手机 在打电话..") } type Camera struct { name string } //让Camera 实现 Usb接口的方法 func (c Camera) Start() { fmt.Println("相机开始工作。。。") } func (c Camera) Stop() { fmt.Println("相机停止工作。。。") } type Computer struct { } func (computer Computer) Working(usb Usb) { usb.Start() //如果usb是指向Phone结构体变量,则还需要调用Call方法 //类型断言..[注意体会!!!] if phone, ok := usb.(Phone); ok { phone.Call() } usb.Stop() } func main() { //定义一个Usb接口数组,可以存放Phone和Camera的结构体变量 //这里就体现出多态数组 var usbArr [3]Usb usbArr[0] = Phone{"vivo"} usbArr[1] = Phone{"小米"} usbArr[2] = Camera{"尼康"} //遍历usbArr //Phone还有一个特有的方法call(),请遍历Usb数组,如果是Phone变量, //除了调用Usb 接口声明的方法外,还需要调用Phone 特有方法 call. =》类型断言 var computer Computer for _, v := range usbArr{ computer.Working(v) fmt.Println() } //fmt.Println(usbArr) }

package main import ( "fmt" ) //定义Student类型 type Student struct { } //编写一个函数,可以判断输入的参数是什么类型 func TypeJudge(items... interface{}) { for index, x := range items { switch x.(type) { case bool : fmt.Printf("第%v个参数是 bool 类型,值是%v\n", index, x) case float32 : fmt.Printf("第%v个参数是 float32 类型,值是%v\n", index, x) case float64 : fmt.Printf("第%v个参数是 float64 类型,值是%v\n", index, x) case int, int32, int64 : fmt.Printf("第%v个参数是 整数 类型,值是%v\n", index, x) case string : fmt.Printf("第%v个参数是 string 类型,值是%v\n", index, x) case Student : fmt.Printf("第%v个参数是 Student 类型,值是%v\n", index, x) case *Student : fmt.Printf("第%v个参数是 *Student 类型,值是%v\n", index, x) default : fmt.Printf("第%v个参数是 类型 不确定,值是%v\n", index, x) } } } func main() { var n1 float32 = 1.1 var n2 float64 = 2.3 var n3 int32 = 30 var name string = "tom" address := "北京" n4 := 300 stu1 := Student{} stu2 := &Student{} TypeJudge(n1, n2, n3, name, address, n4, stu1, stu2) }
作者:华王
博客:https://www.cnblogs.com/huahuawang/