开发者学堂课程【Go 语言核心编程 - 面向对象、文件、单元测试、反射、TCP 编程:实现接口和继承比较(2)】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/626/detail/9826
实现接口和继承比较(2)
内容介绍
一、接口和继承的关系举例说明
二、接口和继承的其他关系
一、接口和继承的关系举例说明
图示为一个比较经典的接口和继承的关系图,图中有两个结构体,其中运动员结构体被篮球运动员和足球运动员这两个结构体所继承,学生这个结构体被大学生和中学生这两个结构体所继承。现在我们有这样的需求,要求足球运动员和大学生掌握英语,有以下几种方式可以实现。第一种直接把学英语技能这个方法写在运动员结构体中,但会存在一个问题,如果写在运动员这个结构体里面,就意味着篮球运动员即使在不想学英语,不需要掌握这个英语技能的情况下,也会被动的接受这个技能,所以直接把这个方法写到运动员结构体中是不合理的,同样的道理,如果把学英语这个方法写在学生这个结构,中学生也被动的接受了学英语的技能,这样也是不合理的。因此利用继承的关系不太容易解决这种需求。但还有一种可能,就是直接把学英语技能的方法直接写在足球运动员上,那么足球运动员就可以去学英语了,同样在大学生这个地方也绑定一个方法,让他去学英语,这样就满足了足球运动员和大学生都可以学英语这个需求了。理论上这种方式是可以的,但在足球运动员结构体和在大学生结构体上分别添加一个学英语的方法,不足之处就是规范性不好。因为在写足球运动员和大学生学英语这个方法的时候,有可能规范就出现了偏差。由于我们希望项目是有规范性的,并不希望足球运动员和大学生学英语写入的方法不一样,比如说他的名字不一样或者是它的参数不一样。因此这个时候需要用接口来实现,这样就可以解决上述产生的问题。首先去定义一个接口,接口叫做学习英语的技能,在接口里面定义相关的方法,然后让足球运动员和大学生来实现这个接口就可以了。这样的好处第一个就是不会影响其他结构体,让足球运动员去实现这个接口,不会影响到篮球运动员,也不影响到运动员整体这个结构体,让大学生去实现这个接口,不会影响到中学生这个结构体,也不会影响到学生整体这个结构体;第二好处就是因为这个接口是已经定义好的,现在让足球运动员和大学生都来实现这个接口,规范性就得到了保证。接口的功能十分具有优势,第一个不破坏继承关系,第二个规范性能够得到保障,我们可以再次体会到接口就是对继承的一种补充,可能大家目前还没有大量去使用接口,因此没有感觉到它的妙用,但的的确确接口可以解决很多的问题。
二、接口和继承的其他关系
1、接口和继承解决的问题其实是不一样的。
(1) 、继承的价值主要在于:解决代码的复用性和可维护性
继承真正的价值主要是解决代码的复用性和可维护性,继承是让一个结构体去继承另外一个结构体,结构体种重复的代码不需要再重复去写,复用性就可以解决;可维护性就是说让被继承的那一个结构体可以通过接口增加一个方法。其结构体也就相应的有了这些字段和方法,因此可维护性也提高了。
(2) 、接口的价值主要在于:设计
接口真正的价值主要在于设计,可以设计好各种规范,其实这些规范就是很多不同的方法,然后让其他自定义类型去实现这些方法即可。因此接口的价值更多的在于设计,尤其是在 golang 里。大家在学习接口的最佳实践案例的时候,应该可以感觉到接口的威力,因为它可以设计好很多规范,只要去实现这个接口就可以,所以这一点是真的很方便。
2、接口比继承更加的灵活
尤其是在 golang 里面,接口是一种很松散的实现机制,所以它比继承更加的灵活,更加方便。例如继承满足 is-a 的关系,比如有 person 和 student 两个结构体,两者之间是 is-a 的关系,即 student is a person。而接口满足 like a的关系,比如说前面写一个接口 BirdAble,还有一个结构体叫 Littlemonkey,我们不可以说猴子是一个鸟,但是可以说猴子可以像小鸟一样飞翔,即通过接口,可以让结构体的功能得到一个扩展。因此他们之间 like a 的关系要弱于is a 的关系。
3、接口在一定程度上可以实现代码解耦
在 golang 里面,接口是一种松散性的实现,并不需要去指定实现的是哪一个接口,只需要去实现这个方法就可以了。
在代码里进行体验,这里的 little monkey 实现了 flying 这个方法,但是并没有指定这个方法是哪一个接口里面的,其重点就是基于这个方法来实现这个接口,所以可以认为接口在一定程度上实现了代码的解耦,非常的灵活。