#### Go 多态
前面两节学习了Go 的继承,接口;那么继承和接口有什么不同呢? 下面我们一起来探讨一下:
继承的价值主要在于: 解决代码的复用性和可维护性;
接口的价值主要在于: 设计,接口设计好各种规范方法,让其它自定义类型实现这些方法
接口比继承更加灵活,继承是满足is-a 的关系,接口是满足like-a 的关系;
下面一起来学习一下多态
变量具有多种形态, 是面向对象编程的第三大特征,Go 中的多态是通过接口实现的;
package main
import "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 main
import "fmt"
func main(){
var a interface{}
var b int
b = 10
a = b // 空接口可以接收任意类型的数据
fmt.Println(a)
//var c int
//c = a // 错误,不能将空接口类型直接赋值给具体的类型, 需要使用类型断言
if c,ok := a.(int);ok {
// 在进行类型断言时,如果类型不匹配,会panic
// 所以在进行类型断方时需要确保空接口指向的就是断言的类型
// 在进行类型断言时可以加上检测机制,就算断言不成功也不会报panic
fmt.Println("assert right")
fmt.Println(c)
} else {
fmt.Println("assert failed")
}
}
##### 类型断言的使用案例
package main
import "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 bool
var b string
var c float64
var d float32
var e int
var f int64
typeAssert(a)
typeAssert(b)
typeAssert(c)
typeAssert(d)
typeAssert(e)
typeAssert(f)
}
案例2:
package main
import "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