go语言interface接口继承多态示例及定义解析
来源:脚本之家
时间:2023-02-25 10:36:35 462浏览 收藏
IT行业相对于一般传统行业,发展更新速度更快,一旦停止了学习,很快就会被行业所淘汰。所以我们需要踏踏实实的不断学习,精进自己的技术,尤其是初学者。今天golang学习网给大家整理了《go语言interface接口继承多态示例及定义解析》,聊聊继承、interface接口、多态,我们一起来看看吧!
1.什么是接口
接口就是一种规范与标准,在生活中经常见接口,例如:笔记本电脑的USB接口,可以将任何厂商生产的鼠标与键盘,与电脑进行链接。为什么呢?原因就是,USB接口将规范和标准制定好后,各个生产厂商可以按照该标准生产鼠标和键盘就可以了。
在程序开发中,接口只是规定了要做哪些事情,干什么。具体怎么做,接口是不管的。这和生活中接口的案例也很相似,例如:USB接口,只是规定了标准,但是不关心具体鼠标与键盘是怎样按照标准生产的.
在企业开发中,如果一个项目比较庞大,那么就需要一个能理清所有业务的架构师来定义一些主要的接口,这些接口告诉开发人员你需要实现那些功能。
2.接口定义
接口定义的语法如下:
方式一:interface接收任意数据格式 //先定义接口 一般以er结尾 根据接口实现功能 type CurrencyEr2 interface{ Symbol() string } 方式二:指定类型 type Currency string
怎样具体实现接口中定义的方法呢?
func (c Currency)Symbol() string { m := "" switch c { case "CNY": // 人民币 m = "¥" case "KRW": // 韩币 m = "₩" case "TWD": // 台币 m = "$" case "JPY": // 日元 m = "¥" case "USD": // 美元 m = "$" } return m }
具体的调用如下:
func main() { // 方式一: a:=CurrencyEr2(Currency("CNY")).Symbol() fmt.Println(a) // 方式二: b:=Currency("CNY").Symbol() fmt.Println(b) }
只要类(结构体)实现对应的接口,那么根据该类创建的对象,可以赋值给对应的接口类型。
接口的命名习惯以er结尾。
3.多态
接口有什么好处呢?实现多态。
多态就是同一个接口,使用不同的实例而执行不同操作
所谓多态指的是多种表现形式,如下图所示:
使用接口实现多态的方式如下:
package main import "fmt" //先定义接口 一般以er结尾 根据接口实现功能 type CurrencyEr2 interface { //方法 方法的声明 Symbol() string } type Currency string type Currency2 string func (c Currency) Symbol() string { m := "" switch c { case "CNY": m = "¥" } return m } func (c Currency2) Symbol() string { m := "" switch c { case "USD": m = "$" } return m } //多态的实现 //将接口作为函数参数 实现多态 func Start(c CurrencyEr2) string { return c.Symbol() } func main() { //调用多态函数 a := Start(Currency("CNY")) fmt.Println(a) //调用多态函数 b := Start(Currency2("USD")) fmt.Println(b) }
多态加减计算器
package main import "fmt" //定义接口 type Opter interface { //方法声明 Result() int } //父类结构体 type Operate struct { num1 int num2 int } //加法子类结构体 type Add struct { Operate } //实现加法子类的方法 func (a *Add) Result() int { return a.num1 + a.num2 } //减法子类结构体 type Sub struct { Operate } //实现减法子类的方法 func (s *Sub) Result() int { return s.num1 - s.num2 } //创建一个类负责对象创建 //工厂类 type Factory struct { } func (f *Factory) Result(num1 int, num2 int, ch string) int { sum := 0 switch ch { case "+": var a Add a.num1 = num1 a.num2 = num2 sum = Opter.Result(&a) case "-": var s Sub s.num1 = num1 s.num2 = num2 sum = Opter.Result(&s) } return sum } //通过设计模式调用 func main() { //创建工厂对象 var f Factory a:= f.Result(10, 20, "+") fmt.Println(a) }
4.接口继承与转换
接口也可以实现继承:
package main import "fmt" //先定义接口 一般以er结尾 根据接口实现功能 type Humaner2 interface { //子集 //方法 方法的声明 sayhi() } type Personer interface { //超集 Humaner2 //继承sayhi() sing(string) } type student13 struct { name string age int score int } func (s *student13)sayhi() { fmt.Printf("大家好,我是%s,今年%d岁,我的成绩%d分\n",s.name,s.age,s.score) } func (s *student13)sing(name string) { fmt.Println("我为大家唱首歌",name) } func main() { //接口类型变量定义 var h Humaner2 var stu student13 = student13{"小吴",18,59} h = &stu h.sayhi() //接口类型变量定义 var p Personer p = &stu p.sayhi() p.sing("大碗面") }
接口继承后,可以实现“超集”接口转换“子集”接口,代码如下:
package main import "fmt" //先定义接口 一般以er结尾 根据接口实现功能 type Humaner2 interface { //子集 //方法 方法的声明 sayhi() } type Personer interface { //超集 Humaner2 //继承sayhi() sing(string) } type student13 struct { name string age int score int } func (s *student13)sayhi() { fmt.Printf("大家好,我是%s,今年%d岁,我的成绩%d分\n",s.name,s.age,s.score) } func (s *student13)sing(name string) { fmt.Println("我为大家唱首歌",name) } func main() { //接口类型变量定义 var h Humaner2 //子集 var p Personer //超集 var stu student13 = student13{"小吴",18,59} p = &stu //将一个接口赋值给另一个接口 //超集中包含所有子集的方法 h = p //ok h.sayhi() //子集不包含超集 //不能将子集赋值给超集 //p = h //err //p.sayhi() //p.sing("大碗面") }
5.空接口
空接口(interface{})不包含任何的方法,正因为如此,所有的类型都实现了空接口,因此空接口可以存储任意类型的数值。
例如:
var i interface{} //接口类型可以接收任意类型的数据 //fmt.Println(i) fmt.Printf("%T\n",i) i = 10 fmt.Println(i) fmt.Printf("%T\n",i)
当函数可以接受任意的对象实例时,我们会将其声明为interface{},最典型的例子是标准库fmt中PrintXXX系列的函数,例如:
func Printf(fmt string, args ...interface{}) func Println(args ...interface{})
如果自己定义函数,可以如下:
func Test(arg ...interface{}) { }
Test( )函数可以接收任意个数,任意类型的参数。
6.接口转换
结论:超集可以转换为子集,子集不可以转换为超集
package main import "fmt" type Humaner interface { //子集 sayhi() } type Personer interface { //超集 Humaner //匿名字段,继承了sayhi() sing(lrc string) } type Student struct { name string id int } //Student实现了sayhi() func (tmp *Student) sayhi() { fmt.Printf("Student[%s, %d] sayhi\n", tmp.name, tmp.id) } func (tmp *Student) sing(lrc string) { fmt.Println("Student在唱着:", lrc) } func main() { //超集可以转换为子集,反过来不可以 var iPro Personer //超集 iPro = &Student{"mike", 666} var i Humaner //子集 //iPro = i //err i = iPro //可以,超集可以转换为子集 i.sayhi() }
7.实现map字典接口
package main import ( "fmt" "sync" ) type UserAges struct { ages map[string] int sync.Mutex } func (u *UserAges)Add(name string,age int) { u.Lock() defer u.Unlock() u.ages[name] = age } func (u *UserAges)Get(name string)int{ if age,ok:=u.ages[name];ok{ return age } return -1 } func main() { dic:=make(map[string]int) dic["age"] = 18 r:=UserAges{ages: dic} r.Add("jeff",20) fmt.Println(r) age:=r.Get("age") fmt.Println(age) }
8.interface案例
package main import "fmt" type Bike interface { save() update() insert() } type User struct { name string } func (this *User) save() { fmt.Println("保存成功", this.name) } func (this *User) update() { fmt.Println("更新成功", this.name) } func (this *User) insert() { fmt.Println("插入成功", this.name) } func main() { var data Bike = &User{name: "jeff"} data.save() data.update() data.insert() }
今天带大家了解了继承、interface接口、多态的相关知识,希望对你有所帮助;关于Golang的技术知识我们会一点点深入介绍,欢迎大家关注golang学习网公众号,一起学习编程~
-
320 收藏
-
149 收藏
-
220 收藏
-
487 收藏
-
344 收藏
-
165 收藏
-
473 收藏
-
377 收藏
-
384 收藏
-
246 收藏
-
110 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 507次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 497次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 484次学习