go语言interface接口继承多态怎么定义
go语言interface接口继承多态怎么定义
本篇内容介绍了“go语言interface接口继承多态怎么定义”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
1.什么是接口
接口就是一种规范与标准,在生活中经常见接口,例如:笔记本电脑的USB接口,可以将任何厂商生产的鼠标与键盘,与电脑进行链接。为什么呢?原因就是,USB接口将规范和标准制定好后,各个生产厂商可以按照该标准生产鼠标和键盘就可以了。
在程序开发中,接口只是规定了要做哪些事情,干什么。具体怎么做,接口是不管的。这和生活中接口的案例也很相似,例如:USB接口,只是规定了标准,但是不关心具体鼠标与键盘是怎样按照标准生产的.
在企业开发中,如果一个项目比较庞大,那么就需要一个能理清所有业务的架构师来定义一些主要的接口,这些接口告诉开发人员你需要实现那些功能。
2.接口定义
接口定义的语法如下:
方式一:interface接收任意数据格式//先定义接口一般以er结尾根据接口实现功能typeCurrencyEr2interface{Symbol()string}方式二:指定类型typeCurrencystring
怎样具体实现接口中定义的方法呢?
func(cCurrency)Symbol()string{m:=""switchc{case"CNY"://人民币m="¥"case"KRW"://韩币m="₩"case"TWD"://台币m="$"case"JPY"://日元m="¥"case"USD"://美元m="$"}returnm}
具体的调用如下:
funcmain(){//方式一:a:=CurrencyEr2(Currency("CNY")).Symbol()fmt.Println(a)//方式二:b:=Currency("CNY").Symbol()fmt.Println(b)}
只要类(结构体)实现对应的接口,那么根据该类创建的对象,可以赋值给对应的接口类型。
接口的命名习惯以er结尾。
3.多态
接口有什么好处呢?实现多态。
多态就是同一个接口,使用不同的实例而执行不同操作
所谓多态指的是多种表现形式,如下图所示:
使用接口实现多态的方式如下:
packagemainimport"fmt"//先定义接口一般以er结尾根据接口实现功能typeCurrencyEr2interface{//方法方法的声明Symbol()string}typeCurrencystringtypeCurrency2stringfunc(cCurrency)Symbol()string{m:=""switchc{case"CNY":m="¥"}returnm}func(cCurrency2)Symbol()string{m:=""switchc{case"USD":m="$"}returnm}//多态的实现//将接口作为函数参数实现多态funcStart(cCurrencyEr2)string{returnc.Symbol()}funcmain(){//调用多态函数a:=Start(Currency("CNY"))fmt.Println(a)//调用多态函数b:=Start(Currency2("USD"))fmt.Println(b)}
多态加减计算器
packagemainimport"fmt"//定义接口typeOpterinterface{//方法声明Result()int}//父类结构体typeOperatestruct{num1intnum2int}//加法子类结构体typeAddstruct{Operate}//实现加法子类的方法func(a*Add)Result()int{returna.num1+a.num2}//减法子类结构体typeSubstruct{Operate}//实现减法子类的方法func(s*Sub)Result()int{returns.num1-s.num2}//创建一个类负责对象创建//工厂类typeFactorystruct{}func(f*Factory)Result(num1int,num2int,chstring)int{sum:=0switchch{case"+":varaAdda.num1=num1a.num2=num2sum=Opter.Result(&a)case"-":varsSubs.num1=num1s.num2=num2sum=Opter.Result(&s)}returnsum}//通过设计模式调用funcmain(){//创建工厂对象varfFactorya:=f.Result(10,20,"+")fmt.Println(a)}
4.接口继承与转换
接口也可以实现继承:
packagemainimport"fmt"//先定义接口一般以er结尾根据接口实现功能typeHumaner2interface{//子集//方法方法的声明sayhi()}typePersonerinterface{//超集Humaner2//继承sayhi()sing(string)}typestudent13struct{namestringageintscoreint}func(s*student13)sayhi(){fmt.Printf("大家好,我是%s,今年%d岁,我的成绩%d分\n",s.name,s.age,s.score)}func(s*student13)sing(namestring){fmt.Println("我为大家唱首歌",name)}funcmain(){//接口类型变量定义varhHumaner2varstustudent13=student13{"小吴",18,59}h=&stuh.sayhi()//接口类型变量定义varpPersonerp=&stup.sayhi()p.sing("大碗面")}
接口继承后,可以实现“超集”接口转换“子集”接口,代码如下:
packagemainimport"fmt"//先定义接口一般以er结尾根据接口实现功能typeHumaner2interface{//子集//方法方法的声明sayhi()}typePersonerinterface{//超集Humaner2//继承sayhi()sing(string)}typestudent13struct{namestringageintscoreint}func(s*student13)sayhi(){fmt.Printf("大家好,我是%s,今年%d岁,我的成绩%d分\n",s.name,s.age,s.score)}func(s*student13)sing(namestring){fmt.Println("我为大家唱首歌",name)}funcmain(){//接口类型变量定义varhHumaner2//子集varpPersoner//超集varstustudent13=student13{"小吴",18,59}p=&stu//将一个接口赋值给另一个接口//超集中包含所有子集的方法h=p//okh.sayhi()//子集不包含超集//不能将子集赋值给超集//p=h//err//p.sayhi()//p.sing("大碗面")}
5.空接口
空接口(interface{})不包含任何的方法,正因为如此,所有的类型都实现了空接口,因此空接口可以存储任意类型的数值。
例如:
variinterface{}//接口类型可以接收任意类型的数据//fmt.Println(i)fmt.Printf("%T\n",i)i=10fmt.Println(i)fmt.Printf("%T\n",i)
当函数可以接受任意的对象实例时,我们会将其声明为interface{},最典型的例子是标准库fmt中PrintXXX系列的函数,例如:
funcPrintf(fmtstring,args...interface{})funcPrintln(args...interface{})
如果自己定义函数,可以如下:
funcTest(arg...interface{}){}
Test( )函数可以接收任意个数,任意类型的参数。
6.接口转换
结论:超集可以转换为子集,子集不可以转换为超集
packagemainimport"fmt"typeHumanerinterface{//子集sayhi()}typePersonerinterface{//超集Humaner//匿名字段,继承了sayhi()sing(lrcstring)}typeStudentstruct{namestringidint}//Student实现了sayhi()func(tmp*Student)sayhi(){fmt.Printf("Student[%s,%d]sayhi\n",tmp.name,tmp.id)}func(tmp*Student)sing(lrcstring){fmt.Println("Student在唱着:",lrc)}funcmain(){//超集可以转换为子集,反过来不可以variProPersoner//超集iPro=&Student{"mike",666}variHumaner//子集//iPro=i//erri=iPro//可以,超集可以转换为子集i.sayhi()}
7.实现map字典接口
packagemainimport("fmt""sync")typeUserAgesstruct{agesmap[string]intsync.Mutex}func(u*UserAges)Add(namestring,ageint){u.Lock()deferu.Unlock()u.ages[name]=age}func(u*UserAges)Get(namestring)int{ifage,ok:=u.ages[name];ok{returnage}return-1}funcmain(){dic:=make(map[string]int)dic["age"]=18r:=UserAges{ages:dic}r.Add("jeff",20)fmt.Println(r)age:=r.Get("age")fmt.Println(age)}
8.interface案例
packagemainimport"fmt"typeBikeinterface{save()update()insert()}typeUserstruct{namestring}func(this*User)save(){fmt.Println("保存成功",this.name)}func(this*User)update(){fmt.Println("更新成功",this.name)}func(this*User)insert(){fmt.Println("插入成功",this.name)}funcmain(){vardataBike=&User{name:"jeff"}data.save()data.update()data.insert()}
“go语言interface接口继承多态怎么定义”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注恰卡编程网网站,小编将为大家输出更多高质量的实用文章!
推荐阅读
-
Go语言中的Goroutine和channel怎么使用
Go语言中的Goroutine和channel怎么使用这篇“Go语...
-
go语言中协程与线程的区别有哪些
go语言中协程与线程的区别有哪些这篇文章主要介绍“go语言中协程与...
-
go语言有哪些好处
go语言有哪些好处这篇文章主要介绍“go语言有哪些好处”的相关知识...
-
Go语言中转义符怎么使用
-
go语言如何判断一个文件是否存在
-
go语言中不定参数指的是什么
-
go语言空白标识符怎么使用
go语言空白标识符怎么使用这篇文章主要介绍了go语言空白标识符怎么...
-
go语言预定义标识符怎么使用
go语言预定义标识符怎么使用本文小编为大家详细介绍“go语言预定义...
-
go语言中join方法怎么使用
go语言中join方法怎么使用这篇“go语言中join方法怎么使用...
-
go语言字符串如何将小写转为大写