如果❤️我的文章有帮助,欢迎点赞、关注。这是对我继续技术创作最大的鼓励。更多往期文章在我的个人博客
简介
Golang interface(接口)是一种抽象的类型,只定义对象的行为规范但不具体实现,具体的规范细节由对象来实现。
使用接口的好处
由于 Golang 中并没有明确的面向对象
编程思想,所以 Golang 也没有面向对象
的类和继承概念。
值得庆幸的是:Golang “十分灵活” 语言特性,使得习惯面向对象编程
的我们,依然能实现面向对象
的特性:封装
、继承
与多态
使用接口概念
的好处在于——它分离 方法
和 具体代码实现逻辑
,让函数更具有适应性。
这么一说你肯定很抽象,但举个数据操作的例子
你就立刻明白了。
如今数据库有很多种: MySQL
、PostgreSQL
、SQL Server
,每一种数据库都有自己具体的数据库连接、操作方法
伪代码实现:
type Mysql struct{}
func (m Mysql) ConnectDB() string {
return "Mysql Database Connect Success"
}
type PostgreSQL struct{}
func (p PostgreSQL) ConnectDB() string {
return "PostgreSQL Database Connect Success"
}
func main() {
mysql := Mysql{}
fmt.Println("mysql connect:", mysql.ConnectDB())
pgsql := PostgreSQL{}
fmt.Println("pgsql connect:", pgsql.ConnectDB())
}
上面的代码定义了Mysql
和PostgreSQL
,然后它们都需要连接数据库。于是你会发现 main()
中有重复的代码。
如果后续再加上SQL Server
、Oracle
等数据库,上面的代码量还会一直增加下去。
这里我们就能把他们抽象
成 数据库
,都需要 连接数据库
、CURD(增删改查)
操作。
让开发者无需考虑数据库差异,差异都隐藏在接口
背后的具体对象
中。
Golang 为了解决类似上面的问题,就设计了接口
概念。
这也是 适配器模式
这一程序设计模式
的思想,接口
是对同一类对象行为的抽象
和概括
。
接口
不会和特定实现细节
绑定在一起,通过这种抽象的方式让我们完成统一的操作。
总结而言:
- 接口是
同一类
对象的约定协议。 同一类对象编写自己不同的实现操作细节
实现接口约定好的方法
- 实现对象不用关心接口会被怎样使用,调用接口也不用关心接口的实现细节。
- Golang 的接口是一种
类型
、抽象结构
,不含具体结构
、数据格式
以及类型
。
接口声明的格式
每个接口类型由数个方法组成。接口的形式代码如下:
type 接口类型名 interface{
方法名1( 参数列表1 ) 返回值列表1
方法名2( 参数列表2 ) 返回值列表2
…
}
对各个部分的说明:
- 接口类型名:使用 type 将接口定义为自定义的类型名。Go 语言的接口在命名时,一般会在单词后面添加 er,如有写操作的接口叫 Writer,有字符串功能的接口叫 Stringer,有关闭功能的接口叫 Closer 等。
- 方法名:当方法名首字母是大写时,且这个接口类型名首字母也是大写时,这个方法可以被接口所在的包(package)之外的代码访问。
- 参数列表、返回值列表:参数列表和返回值列表中的参数变量名可以被忽略,例如:
type writer interface{
Write([]byte) error
}
type writer interface{
Write([]byte) error
}
开发中常见的接口及写法
Go 语言提供的很多包中都有接口,例如 io 包中提供的 Writer 接口:
- type Writer interface {
- Write(p []byte) (n int, err error)
- }
type Writer interface { Write(p []byte) (n int, err error) }
这个接口可以调用 Write() 方法写入一个字节数组([]byte),返回值告知写入字节数(n int)和可能发生的错误(err error)。
类似的,还有将一个对象以字符串形式展现的接口,只要实现了这个接口的类型,在调用 String() 方法时,都可以获得对象对应的字符串。在 fmt 包中定义如下:
- type Stringer interface {
- String() string
- }
type Stringer interface { String() string }
Stringer 接口在 Go 语言中的使用频率非常高,功能类似于 Java 或者 C# 语言里的 ToString 的操作。
Go 语言的每个接口中的方法数量不会很多。Go 语言希望通过一个接口精准描述它自己的功能,而通过多个接口的嵌入和组合的方式将简单的接口扩展为复杂的接口。本章后面的小节中会介绍如何使用组合来扩充接口。