在本篇中,我们先学会:
- 鸭式辨型
- interface是行为抽象的封装,它可以被任意类型无感知实现
- interface在golang中重要性及意义
开始之前,我们先了解一个概念: 鸭式辨型
鸭式辨型:像鸭子一样走路并且嘎嘎叫的就叫鸭子;
假如有一种动物,走起路来像鸭子,叫声嘎嘎嘎嘎,没错,它就是鸭子;就好比只要长有四肢和脑袋且用双脚走路的就是人,按照这个理论,袋鼠也是人:拥有四肢和脑袋,用双脚走路。不信你去看看,它是不是像人。
希望你不介意,刚才用人来开了个玩笑;鸭式辨型的思想是:通过制定规则来判定对象是否实现这个接口
interface是行为抽象的封装,它可以被任意类型无感知实现
在编程语言中,数据类型的抽象,是一种很重要的思想,比如像java这样的语言,就有“一切皆对象”的高度抽象思维;golang中interface就是为了实现数据行为的抽象和封装。比如下面的列子:
type Dog interface {
SetName(name string)
SetSex(sex string)
}
定义了一个Dog的接口类型,包含了两个方法SetName设置狗的名字,SetSex设置狗的性别;对于接口类型:
- 接口类型无法实例化,它只是某种数据类型的声明
- 接口类型不能包含字段属性,仅仅在大括号内包裹方法的定义
- 对于某种数据类型,如果它实现了接口类型中的全部方法,那它一定是这个接口的实现类型(鸭式辨型)
对于第一点和第二点,接口类型是一种行为抽象类型,实例化并无意义,struct结构体类型包裹的是字段声明,接口类型包裹的是方法定义;针对第三点,用下面的列子来介绍:
type Husky struct {
Name string
Sex string
}
func (h Husky)SetName(name string) {
h.Name = name
}
func (h Husky)SetSex(sex string) {
h.Sex = sex
}
func main() {
var husky Husky = Husky{
Name:"阿黄",
Sex:"male",
}
var dog Dog = husky
dog.SetName("旺财")
}
代码中我们声明了一个结构体类型Husky ,实现了 SetName和SetSex方法,因此它Husky类型是Dog类型的实现,var dog Dog = husky1 将一个Husky类型的变量赋值给Dog类型的变量。这是合理的,根据鸭式辨型的定义,Husky实现了Dog类型的规则,因此它就是Dog类型。
从代码中我们可以看到, golang中这种类型的转换,它不需要一个强行的关联(比如java中implement、extends关键字),而只需要长的像,实现了它的行为,即可是它的类型。
理解以上基础概念之后,下面我们来解决几个问题加深学习:
1. dog 是interface类型,husky是struct类型,将 husky 赋值给dog变量之后,dog的存储结构和husky有何区别;
2. 接口类型的变量,可以被满足鸭式辨型的实例赋值,因此接口类型变量有静态类型、动态类型、动态值的解读;
3. 在go语言中,怎么实现接口组合,提高代码可阅读性;
4. 对于interface,如果是空的,它在go语言中,代表什么;