多态是面向对象的三大基本特性之一。多态是指对于不同的实例,同样的操作可能会有不同的表现形式。例如加法操作,如果操作的数据是数,那么它对两个数进行求和;如果操作的数据是字符串,那么它将连接两个字符串。
多态机制使具有不同内部结构的对象可以共享相同的外部接口。这意味着,虽然针对不同对象的具体操作不同,但通过一个公共的类,那些操作可以通过相同的方式予以调用。这样可以减少代码的复杂度。
在Go语言里,定义这些操作的类叫作接口(interface)。
1
接口的概述
在Go语言中,接口是一个自定义类型,具体描述了一系列方法的集合。它是一种抽象的类型,不会暴露出它所代表的对象的内部值结构和这个对象支持的基础操作的集合,它们只会展示出它们自己的方法,即接口指定了一个类型应该具有的方法,并由该类型决定如何实现这些方法。
在Go语言中,当一个类型定义了接口中的所有方法,我们称它实现了该接口。
2
接口的定义与实现
2.1 接口的定义
接口的定义格式与结构体类似,接口的定义需要关键词type和interface。定义如下:
注:a. 接⼝命名习惯上以er结尾;
b.接口中只有方法声明,没有数据字段。
2.2 接口的实现
接口是用来定义行为的类型。这些被定义的行为不由接口直接实现,而是通过方法由用户定义的类型来实现。在Go语言中,用户定义的类型实现了接口声明的所有方法,那么这个类型就隐式地实现了这个接口,而这个类型就是实现这个接口类型的实例。
接口可以分为普通接口和嵌入接口。普通接口指的是定义了一组方法的接口,嵌入接口指的是一个接口里嵌入了其他接口。
2.2.1 普通接口的实现
普通接口的实现,即对象的类型实现了普通接口里定义的所有方法。接口对对象的类型没有限制,既可以是值类型,也可以是指针类型。
2.2.2 嵌入接口的实现
接口可以匿名嵌入其它接口,Go语言没有提供继承机制,但可以通过嵌套其他的接口,创建一个新接口。
如果一个interface1作为interface2的一个嵌入字段,那么interface2隐式的包含了interface1里面的方法。
3
接口类型变量的赋值
在Go语言中能实现接口类型变量赋值的有两种情况:将对象实例赋值给接口类型变量,将一个接口类型变量赋值给另一个接口类型变量。
3.1 将对象实例赋值给接口类型变量
将某种类型的对象实例赋值给接口类型变量,这要求该对象实例实现了接口要求的所有方法。这个赋值会把用户定义的类型值存入到这个接口类型的变量。
如果对象实例实现了接口中的所有方法,这些方法的接收者类型中有一个是指针类型,那么赋值给这个接口变量的对象实例必须是指针类型。如果将一个值类型的实例赋值给此接口变量,程序在编译期出错,这是因为接口中存储的具体值并不能取到地址,无法实现接收者类型为指针类型的方法。
如果对象实例实现接口的所有方法的接收者类型都是值类型,那么赋值给接口类型变量的实例既可以是值类型,也可以是指针类型,因为接口中存储的地址可以取到值,这也就实现了接收者类型为值类型的方法。
3.2 将一个接口赋值给另一个接口
如果接口A的方法列表是接口B的方法列表的子集,那么接口B可以赋值给接口A。接口B被称作超集接口,接口A被称作子集接口。超集接口的对象可转换为子集接口,反之出错。
4
空接口
没有包含方法的接口称为空接口,空接口表示为“interface{}”。由于空接口没有方法,因此所有类型都实现了空接口,因此空接口可以存储任意类型的数值。
5
类型查询
接口的内部结构可以看作一对“type:value”:type 是接口底层的具体类型,而 value 是具体类型所对应的值。
根据接口变量反向确认接口类型变量保存的类型和值的方法有两种:类型断言和类型选择。
5.1 类型断言
类型断言用于提取接口的底层值。Go语言存在一个语法:根据断言的类型判断这个接口变量是否存储的是该类型值。其语法格式如下:
注:a. i是接口变量;
b. T是断言的类型,value是存储在接口变量里与类型T对应的值;
c. ok是布尔值:如果T和value是接口底层的类型和值,ok返回true,否则返回false。
5.2 类型选择
类型选择用于将接口的具体类型与很多case 语句所指定的类型进行比较。它与一般的 switch 语句类似,唯一的区别在于类型选择指定的是类型,而一般的switch指定的是值。
类型选择的语法类似于类型断言。类型断言的语法是 i.(T),而对于类型选择,类型 T 由关键字 type 代替,如下所示:
注:当某一个case语句之后的类型通过i.(type)得到的接口底层值不为空,则执行该case之后的语句。
参考资料:
[1] 谭浩强.C++面向对象程序设计[M]. 清华大学出版社,2006
[2] 陈维兴,陈昕.C++面向对象程序设计[M]. 人民邮电出版社,2010
[3] https://www.studygolang.com/articles/12266
[4] https://studygolang.com/articles/12325
[5] 许式伟,吕桂华.Go语言编程[M].北京:人民邮电出版社,2012:74-78.
本文完,获取更多资讯,敬请关注区块链工程师。
领取专属 10元无门槛券
私享最新 技术干货