当前位置: 首页 > article >正文

golang学习笔记23-面向对象(五):多态与断言【重要】

本节也是GO核心部分,很重要。
注:由于导包语句已经在19讲(笔记19:面向对象的引入)展示过了,所以这里就不展示了。

一、多态(Polymorphism)

变量(实例)具有多种形态,即多态,是面向对象的第三大特征,在Go语言,多态特征是通过接口实现的。可以按照统一的接口来调用不同的实现。这时接口变量就呈现不同的形态。比如上一讲的greet的参数:s SayHello就是多态参数,这个参数有中国人和美国人两种形态。那么在此之上,我们还可以定义多态数组,来存放不同形态的。示例,首先在之前定义好的Chinese和American结构体中添加名称字段,即Name string,然后在main中测试:

func main() {
	var arr [3]utils.SayHello
	arr[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,ok=element.(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

http://www.kler.cn/a/326677.html

相关文章:

  • 功能测试和接口测试
  • 光谱相机与普通相机的区别
  • Bash Shell知识合集
  • C++第五六单元测试
  • Cursor提示词
  • RestTemplate关于https的使用详解
  • C++学习9.24
  • git本地分支落后于远程分支,因此推送被拒绝怎么办?
  • nodejs逐字读取文件示例
  • Python中的`super()`函数:掌握面向对象编程的艺术
  • PHP“===”的意义
  • 工具类:JWT
  • 【AI学习】Lilian Weng:Extrinsic Hallucinations in LLMs(LLM 的外在幻觉)
  • TS-AI:一种用于多模态个体化脑区划分的深度学习管道,并结合任务对比合成|文献速递-Transformer架构在医学影像分析中的应用
  • 生产环境升级mysql流程及配置主从服务
  • YOLOv8改进 | 主干篇,YOLOv8改进主干网络为华为的轻量化架构GhostNetV1
  • C++ 左值右值引用梳理(一)
  • 蓝桥杯—STM32G431RBT6(RTC时钟获取时间和日期)
  • python 如何引用变量
  • LeetCode 每日一题 最佳观光组合
  • 水波荡漾效果+渲染顺序+简单UI绘制
  • Chromium 屏蔽“缺少 Google API 密钥,因此 Chromium 的部分功能将无法使用。”提示 c++
  • Conda 虚拟环境使用指南,python,anaconda,miniconda
  • MySQL InnoDB 事务commit逻辑分析
  • C++的new关键字
  • 如何在Android上运行Llama 3.2