當前位置:
首頁 >
Go 多态
發布時間:2025/3/20
27
豆豆
#### Go 多態
前面兩節學習了Go 的繼承,接口;那么繼承和接口有什么不同呢? 下面我們一起來探討一下:
繼承的價值主要在于: 解決代碼的復用性和可維護性;
接口的價值主要在于: 設計,接口設計好各種規范方法,讓其它自定義類型實現這些方法
接口比繼承更加靈活,繼承是滿足is-a 的關系,接口是滿足like-a 的關系;
下面一起來學習一下多態
變量具有多種形態, 是面向對象編程的第三大特征,Go 中的多態是通過接口實現的; package mainimport "fmt"type USB interface {Start()Stop() } type Phone struct {} type Camera struct {}func (p *Phone) Start(){fmt.Println("phone is working") } func (p *Phone) Stop(){fmt.Println("phone stop work") } func (c *Camera) Start(){fmt.Println("camera is working") } func (c *Camera) Stop(){fmt.Println("camera stop work") } func working(usb USB) {usb.Start()usb.Stop() } func main(){var phone = new(Phone)var camera = new(Camera)working(phone)working(camera) }
說明:
wroking 方法即可以接收Phone 類型的變量,也可以接收Camera 類型的變量,體現出了USB 接口的多態
接口多態有以下兩種形式:
1. 多態參數: 比如上面的例子
2. 多態數組或切片 var USBArray [3]USB USBArray[0] = &Phone{} USBArray[1] = &Camera{}
##### 類型斷言
如何將一個接口類型的數據,賦值給具體類型? 需要使用到類型斷言; package mainimport "fmt"func main(){var a interface{}var b intb = 10a = b // 空接口可以接收任意類型的數據fmt.Println(a)//var c int//c = a // 錯誤,不能將空接口類型直接賦值給具體的類型, 需要使用類型斷言if c,ok := a.(int);ok {// 在進行類型斷言時,如果類型不匹配,會panic// 所以在進行類型斷方時需要確保空接口指向的就是斷言的類型// 在進行類型斷言時可以加上檢測機制,就算斷言不成功也不會報panicfmt.Println("assert right")fmt.Println(c)} else {fmt.Println("assert failed")} }
##### 類型斷言的使用案例 package mainimport "fmt"// 編寫一下函數,可以接收任意類型的數據 func typeAssert(data interface{}) {switch data.(type) {case bool:fmt.Println("data type is bool")case string:fmt.Println("data type is string")case float64:fmt.Println("data type is float64")case float32:fmt.Println("data type is float32")case int,int64:fmt.Println("data type is int")default:fmt.Println("data type is unknow")} } func main() {var a boolvar b stringvar c float64var d float32var e intvar f int64typeAssert(a)typeAssert(b)typeAssert(c)typeAssert(d)typeAssert(e)typeAssert(f) }
案例2: package mainimport "fmt"type USB interface {Start()Stop() } type Phone struct {Name string } type Camera struct {Name string } func (p *Phone) Start(){fmt.Println(p.Name,"is working") } func (p *Phone) Stop(){fmt.Println(p.Name,"stop work") } func (p *Phone) Call(){fmt.Println(p.Name,"is calling") } func (c *Camera) Start(){fmt.Println(c.Name,"is working") } func (c *Camera) Stop(){fmt.Println(c.Name,"stop work") } func (c *Camera) Shoot(){fmt.Println(c.Name,"is shooting") } func work(usb USB) {usb.Start()// 實際類型實現接口還有其它的方法if phone,ok := usb.(*Phone);ok {phone.Call()}if camera,ok := usb.(*Camera);ok {camera.Shoot()}usb.Stop() } func main(){var phone = &Phone{Name:"apple"}var camera = &Camera{Name:"nikon"}work(phone)work(camera) }
今天就寫這么多吧, Go 基本語法部分大概學習完了,學習完這部分后
大家可以嘗試做一些小項目,鞏固一下基礎知識;后面還有單元測試,協程,通道,反射四個基礎章節;
學習完最后四個章節后,會介紹一些Go 的生態以及平常工作中使用到的類庫;
個人微信公眾號上有最新文章,歡迎關注一同交流學習
前面兩節學習了Go 的繼承,接口;那么繼承和接口有什么不同呢? 下面我們一起來探討一下:
繼承的價值主要在于: 解決代碼的復用性和可維護性;
接口的價值主要在于: 設計,接口設計好各種規范方法,讓其它自定義類型實現這些方法
接口比繼承更加靈活,繼承是滿足is-a 的關系,接口是滿足like-a 的關系;
下面一起來學習一下多態
變量具有多種形態, 是面向對象編程的第三大特征,Go 中的多態是通過接口實現的; package mainimport "fmt"type USB interface {Start()Stop() } type Phone struct {} type Camera struct {}func (p *Phone) Start(){fmt.Println("phone is working") } func (p *Phone) Stop(){fmt.Println("phone stop work") } func (c *Camera) Start(){fmt.Println("camera is working") } func (c *Camera) Stop(){fmt.Println("camera stop work") } func working(usb USB) {usb.Start()usb.Stop() } func main(){var phone = new(Phone)var camera = new(Camera)working(phone)working(camera) }
說明:
wroking 方法即可以接收Phone 類型的變量,也可以接收Camera 類型的變量,體現出了USB 接口的多態
接口多態有以下兩種形式:
1. 多態參數: 比如上面的例子
2. 多態數組或切片 var USBArray [3]USB USBArray[0] = &Phone{} USBArray[1] = &Camera{}
##### 類型斷言
如何將一個接口類型的數據,賦值給具體類型? 需要使用到類型斷言; package mainimport "fmt"func main(){var a interface{}var b intb = 10a = b // 空接口可以接收任意類型的數據fmt.Println(a)//var c int//c = a // 錯誤,不能將空接口類型直接賦值給具體的類型, 需要使用類型斷言if c,ok := a.(int);ok {// 在進行類型斷言時,如果類型不匹配,會panic// 所以在進行類型斷方時需要確保空接口指向的就是斷言的類型// 在進行類型斷言時可以加上檢測機制,就算斷言不成功也不會報panicfmt.Println("assert right")fmt.Println(c)} else {fmt.Println("assert failed")} }
##### 類型斷言的使用案例 package mainimport "fmt"// 編寫一下函數,可以接收任意類型的數據 func typeAssert(data interface{}) {switch data.(type) {case bool:fmt.Println("data type is bool")case string:fmt.Println("data type is string")case float64:fmt.Println("data type is float64")case float32:fmt.Println("data type is float32")case int,int64:fmt.Println("data type is int")default:fmt.Println("data type is unknow")} } func main() {var a boolvar b stringvar c float64var d float32var e intvar f int64typeAssert(a)typeAssert(b)typeAssert(c)typeAssert(d)typeAssert(e)typeAssert(f) }
案例2: package mainimport "fmt"type USB interface {Start()Stop() } type Phone struct {Name string } type Camera struct {Name string } func (p *Phone) Start(){fmt.Println(p.Name,"is working") } func (p *Phone) Stop(){fmt.Println(p.Name,"stop work") } func (p *Phone) Call(){fmt.Println(p.Name,"is calling") } func (c *Camera) Start(){fmt.Println(c.Name,"is working") } func (c *Camera) Stop(){fmt.Println(c.Name,"stop work") } func (c *Camera) Shoot(){fmt.Println(c.Name,"is shooting") } func work(usb USB) {usb.Start()// 實際類型實現接口還有其它的方法if phone,ok := usb.(*Phone);ok {phone.Call()}if camera,ok := usb.(*Camera);ok {camera.Shoot()}usb.Stop() } func main(){var phone = &Phone{Name:"apple"}var camera = &Camera{Name:"nikon"}work(phone)work(camera) }
今天就寫這么多吧, Go 基本語法部分大概學習完了,學習完這部分后
大家可以嘗試做一些小項目,鞏固一下基礎知識;后面還有單元測試,協程,通道,反射四個基礎章節;
學習完最后四個章節后,會介紹一些Go 的生態以及平常工作中使用到的類庫;
個人微信公眾號上有最新文章,歡迎關注一同交流學習
轉載于:https://www.cnblogs.com/Mail-maomao/p/11492675.html
總結
- 上一篇: Go 接口
- 下一篇: js 为什么0.1+0.2不等于0.3