垦利住房和城乡建设局网站,做it人经常逛的网站,网页设计与制作课程思政目标,wordpress 数据库 发布本节也是GO核心部分#xff0c;很重要。 注#xff1a;由于导包语句已经在19讲#xff08;笔记19#xff1a;面向对象的引入#xff09;展示过了#xff0c;所以这里就不展示了。
一、多态#xff08;Polymorphism#xff09;
变量#xff08;实例#xff09;具有多…本节也是GO核心部分很重要。 注由于导包语句已经在19讲笔记19面向对象的引入展示过了所以这里就不展示了。
一、多态Polymorphism
变量实例具有多种形态即多态是面向对象的第三大特征在Go语言多态特征是通过接口实现的。可以按照统一的接口来调用不同的实现。这时接口变量就呈现不同的形态。比如上一讲的greet的参数s SayHello就是多态参数这个参数有中国人和美国人两种形态。那么在此之上我们还可以定义多态数组来存放不同形态的。示例首先在之前定义好的Chinese和American结构体中添加名称字段即Name string然后在main中测试
func main() {var arr [3]utils.SayHelloarr[0] utils.Chinese{李华}arr[1] utils.American{Lily}arr[2] utils.Chinese{赵六}fmt.Println(arr)
}注意类似arr[0].Name是错的因为接口并不暴露具体实现类型的字段。要访问 Name字段可以创建一个方法来返回名称。比如在 Chinese 和 American 结构体中定义一个 GetName() 方法但这种方法显然太繁了其实GO可以直接将接口类型转换为具体的类型这就是接下来要说的断言。
二、断言Assertion
【1】什么是断言? Go语言里面有一个语法可以直接判断是否是该类型的变量var x,okelement.(T)这里value就是变量的值ok是一个bool类 型element是interface变量T是断言的类型。 【2】断言的案例引入在utils中定义中国人结构体的新方法
func (c Chinese) NiuYangGe() {fmt.Println(东北人扭秧歌)
}此时如果在Greet函数中添加s.NiuYangGe()就会报错type utils.SayHello has no field or method NiuYangGe。意思是接口中没有NiuYangGe()这个方法但这其实不是接口声明的问题是编译器不知道传入的这个接口变量是哪个类型的即Chinese的还是American的所以要把它改为断言语句所以在Greet函数的代码如下
func Greet(s SayHello) {s.Say()c, flag : s.(Chinese)if flag {c.NiuYangGe()} else {fmt.Println(美国人没有扭秧歌)}
}当然如果知道s能转为Chinese即Chinese有NiuYangGe()这个方法也可以简写
c2 : s.(Chinese)
c2.NiuYangGe()那么一般来说还是采用第一种方法这样严谨。 这样一来我们在main中就可以正确调用新方法了
func main() {var c utils.SayHello utils.Chinese{}utils.Greet(c)
}【3】Type Switch的基本用法Type Switch是Go语言中一种特殊的switch语句它比较的是类型而不是具体的值。它判断某个接口变量的类型然后根据具体类型再做相应处理。首先在utils中增加新方法
func (a American) Disco() {fmt.Println(Disco)
}然后在Greet()中判断代替第二点的判断语句
func Greet(s SayHello) {s.Say()// c, flag : s.(Chinese)// if flag {// c.NiuYangGe()// } else {// fmt.Println(美国人没有扭秧歌)// }// c2 : s.(Chinese)// c2.NiuYangGe()switch person : s.(type) {case Chinese:person.NiuYangGe()case American:person.Disco()default:fmt.Println(未知类型)}
}最后在main中调用
func main() {var c utils.SayHello utils.Chinese{}utils.Greet(c)c utils.American{}utils.Greet(c)
}程序输出如下
你好
东北人扭秧歌
hello
Disco