前言

预备知识

本教程假定你已经知道了:

  • 基本的Go语言基础知识
  • 其他编译强类型语言的学习效果更佳

    学习收获

    读完这篇教程后,你将掌握 Django MTV 框架的精髓:

  • M(Model):创建数据模型,并执行数据库迁移

  • T(Template):写出基本的 Django 模板,并从视图中传入数据
  • V(View):在视图中访问数据库,实现业务逻辑,渲染模板,并接入路由表

    一、接口的概念

    面向接口编程

    接口是什么

    接口是一组仅包含方法名、参数、返回值的未具体实现的方法的集合。 ```java package demos;

interface BaseInterface { //声明BaseInterface接口 public void speak(); //声明抽象方法speak }

public class DuckClass implements BaseInterface { //实现BaseInterface接口 public void speak(){//实现抽象方法speak System.out.println(“嘎嘎嘎”); }

  1. public static void main(String args[]){
  2. Duck duck1 = new Duck();
  3. duck1.speak();
  4. }

}

  1. Java中实现接口是显式的(implements),而在Golang中接口是**隐式**地实现。
  2. <a name="IsuQX"></a>
  3. ## 为什么需要使用接口?
  4. - 大型项目解耦 方便测试
  5. - 可维护性
  6. - 实现面向对象多态
  7. - 高内聚 低耦合
  8. - 团队项目规范开发
  9. <a name="Vw7Oe"></a>
  10. ## 生活中的接口
  11. usb插槽就是生活中的接口<br />你可以把手机、相机插到usb插槽上,对于接口来说,我并不关心你插的手机还是相机,只要你插上,我都能识别。
  12. <a name="OjkP4"></a>
  13. #
  14. <a name="lsCB2"></a>
  15. ## 接口的作用
  16. - 实现面向对象的多态
  17. - 可维护性、拓展性(定义接口,将业务抽象成接口方法,将接口指向实现的类,只需要更换一处,实现可扩展性)
  18. - 团队项目规范开发(将业务抽象定义一些接口,分配人员去具体实现)
  19. - <br />
  20. <a name="jWh13"></a>
  21. # 二、Go接口使用
  22. <a name="4ifcU"></a>
  23. ## 接口定义
  24. Go语言中,接口是一组未实现方法的声明集合,当一个自定义类型的方法为接口中的方法提供实现时,那么这个类型就实现了该接口。
  25. **语法**<br />与struct类似,我们需要使用类型别名,通过interface关键字来简化接口声明。
  26. ```go
  27. type interfaceName interface {
  28. //抽象方法列表
  29. methodName(parameter list) returnType
  30. }

实例

  1. package intertest
  2. type People interface { //定义People接口
  3. GetName(name string) string //声明抽象方法GetName
  4. }

上面的代码中,我们定义了People接口,它有一个抽象方法GetName,它接受一个name为string类型的参数返回值是string。在Go语言中任何实现这个方法的类型我们都认为它实现了People接口。

Go语言接口特点

  • Go语言接口只含一组未实现方法的声明集合,不能包含变量(区别于Java)
  • Go语言接口是隐式的实现。(区别于Java的implements)
  • Go语言自定义类型都可以实现接口,不仅是结构体。
  • 一个自定义类型可以实现多个接口

image.png
image.png

实现接口

image.png
image.png

  1. package main
  2. import (
  3. "fmt"
  4. "interfaceTest/intertest"
  5. )
  6. //定义一个结构体
  7. type Student struct {
  8. }
  9. //为Student结构体定义一个GetName方法 ,该Student结构体实现了People接口
  10. func (stud Student)GetName(name string) string {
  11. return "我的名字是:"+stud.name
  12. }
  13. func main( ) {
  14. var man intertest.People = Student{}
  15. fmt.Println(man.GetName("小白"))
  16. }


空接口

一个不包含任何方法的接口,称之为空接口interface{}因为空接口不包含任何方法,所以Go语言中所有类型都默认实现空接口。(换句话说,所有类型都实现了至少0个方法,所有类型都实现空接口)

空接口在需要存储任意类型的变量的时候非常有用。举个例子,fmt包里的Println函数可以接收任意类型的
变量,比如int、string、silce等等。为什么,因为它的形参就是空接口类型,可以接收任意类型的变量。

  1. func Println(a ...interface{}) (n int, err error) {
  2. return Fprintln(os.Stdout, a...)
  3. }
  1. type Empty interface {
  2. }
  3. //简写
  4. type empty_int interface{}

更常见的,会直接使用interface{}作为一组数据类型,既空接口可以传入任意类型的变量,例如

  1. var i interface{}=5
  2. //函数使用空接口类型参数
  3. func myfunc(i interface{})

可以定义一个空接口类型的array、slice、map、struct等,这样它们就可以用来存放任意类型的对象,因为任意类型都实现了空接口

接口的组合

在Go语言中,不仅结构体与结构体之间可以嵌套,接口与接口间也可以通过嵌套创造出新的接口。

接口变量的内存布局

image.png
接口变量中含有实现者的类型和实现者指针

image.png

实现接口和继承的区别

image.png
有如下需求:如果要让足球运动员、大学生都要掌握英语技能,可以采用2种方法:(1)足球运动员绑定一个英语方法,大学生绑定一个英语方法。(2)写一个英语技能的接口,足球运动员、大学生实现此接口。很显然方法2保证了实现方法(技能要求)的一致性。
Go语言接口 - 图8Go语言接口 - 图9

类型断言

类型断言
类型断言(type assertion)是一种使用在接口变量上的操作,常用来反向提取空接口类型中所指向的真实类型

语法格式

  1. //非安全类型断言,断言失败则报painc错误
  2. v:=i.(T)
  3. //非安全类型断言
  4. v,ok:=i.(T)

应用例子
有时候,我们可能需要做的某个接口类型中的实际指向类型,比如一个方法需要传入多种类型参数并判断具体的类型时。

image.png
image.png

参考文档