前言
预备知识
本教程假定你已经知道了:
- 基本的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(“嘎嘎嘎”); }
public static void main(String args[]){
Duck duck1 = new Duck();
duck1.speak();
}
}
在Java中实现接口是显式的(implements),而在Golang中接口是**隐式**地实现。
<a name="IsuQX"></a>
## 为什么需要使用接口?
- 大型项目解耦 方便测试
- 可维护性
- 实现面向对象多态
- 高内聚 低耦合
- 团队项目规范开发
<a name="Vw7Oe"></a>
## 生活中的接口
usb插槽就是生活中的接口<br />你可以把手机、相机插到usb插槽上,对于接口来说,我并不关心你插的手机还是相机,只要你插上,我都能识别。
<a name="OjkP4"></a>
#
<a name="lsCB2"></a>
## 接口的作用
- 实现面向对象的多态
- 可维护性、拓展性(定义接口,将业务抽象成接口方法,将接口指向实现的类,只需要更换一处,实现可扩展性)
- 团队项目规范开发(将业务抽象定义一些接口,分配人员去具体实现)
- <br />
<a name="jWh13"></a>
# 二、Go接口使用
<a name="4ifcU"></a>
## 接口定义
在Go语言中,接口是一组未实现方法的声明集合,当一个自定义类型的方法为接口中的方法提供实现时,那么这个类型就实现了该接口。
**语法**<br />与struct类似,我们需要使用类型别名,通过interface关键字来简化接口声明。
```go
type interfaceName interface {
//抽象方法列表
methodName(parameter list) returnType
}
实例
package intertest
type People interface { //定义People接口
GetName(name string) string //声明抽象方法GetName
}
上面的代码中,我们定义了People接口,它有一个抽象方法GetName,它接受一个name为string
类型的参数返回值是string
。在Go语言中任何实现这个方法的类型我们都认为它实现了People接口。
Go语言接口特点
- Go语言接口只含一组未实现方法的声明集合,不能包含变量(区别于Java)
- Go语言接口是隐式的实现。(区别于Java的implements)
- Go语言自定义类型都可以实现接口,不仅是结构体。
- 一个自定义类型可以实现多个接口
实现接口
package main
import (
"fmt"
"interfaceTest/intertest"
)
//定义一个结构体
type Student struct {
}
//为Student结构体定义一个GetName方法 ,该Student结构体实现了People接口
func (stud Student)GetName(name string) string {
return "我的名字是:"+stud.name
}
func main( ) {
var man intertest.People = Student{}
fmt.Println(man.GetName("小白"))
}
空接口
一个不包含任何方法的接口,称之为空接口interface{}
。因为空接口不包含任何方法,所以Go语言中所有类型都默认实现空接口。(换句话说,所有类型都实现了至少0个方法,所有类型都实现空接口)
空接口在需要存储任意类型的变量的时候非常有用。举个例子,fmt包里的Println函数可以接收任意类型的
变量,比如int、string、silce等等。为什么,因为它的形参就是空接口类型,可以接收任意类型的变量。
func Println(a ...interface{}) (n int, err error) {
return Fprintln(os.Stdout, a...)
}
type Empty interface {
}
//简写
type empty_int interface{}
更常见的,会直接使用interface{}
作为一组数据类型,既空接口可以传入任意类型的变量,例如
var i interface{}=5
//函数使用空接口类型参数
func myfunc(i interface{})
可以定义一个空接口类型的array、slice、map、struct等,这样它们就可以用来存放任意类型的对象,因为任意类型都实现了空接口
接口的组合
在Go语言中,不仅结构体与结构体之间可以嵌套,接口与接口间也可以通过嵌套创造出新的接口。
接口变量的内存布局
接口变量中含有实现者的类型和实现者指针
实现接口和继承的区别
有如下需求:如果要让足球运动员、大学生都要掌握英语技能,可以采用2种方法:(1)足球运动员绑定一个英语方法,大学生绑定一个英语方法。(2)写一个英语技能的接口,足球运动员、大学生实现此接口。很显然方法2保证了实现方法(技能要求)的一致性。
。
类型断言
类型断言
类型断言(type assertion)是一种使用在接口变量上的操作,常用来反向提取空接口类型中所指向的真实类型
语法格式
//非安全类型断言,断言失败则报painc错误
v:=i.(T)
//非安全类型断言
v,ok:=i.(T)
应用例子
有时候,我们可能需要做的某个接口类型中的实际指向类型,比如一个方法需要传入多种类型参数并判断具体的类型时。