Go 语言快速入门指南:接口(一)

911 阅读4分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第 10 天,点击查看活动详情

1. 接口是什么?

接口 是一组仅包含方法名参数返回值的未具体实现的方法的集合,它像是一个公司里面的领导,他会定义一些通用规范,只设计规范,而不实现规范。

Go语言中接口是一种抽象的类型。

Go 语言的接口遵守LSP(里氏替换原则),即 一个类型可以自由地被另一个满足相同接口的类型替换。

2. 为什么需要接口?

大多情况下,一些数据可能包含不同的类型,但是可能会有一个或者多个共同点,这些共同点就是抽象的基础。

Go的接口类似c++的多态,接口相当于实现一个父类,然后派生类具体实现父类的虚函数,最后通过父类指针指向不同的派生类对象去调用那个派生类对象的虚函数,从而实现多态

于是乎,接口出现了。接口可以理解为某一个方面的抽象,可以是多对一的(多个类型实现一个接口),这也是多态的体现。

举例说明一下,比如三角形,四边形,圆形都能计算面积,那就可以在图形接口中写一个计算面积的方法,然后每一种图形都可以具体去实现它,这样就能计算自己的面积(每种图形计算面积的公式不同)了,大概就是这个意思。

3. 接口的定义

type 接口类型名 interface{
    方法名1( 参数列表1 ) 返回值列表1
    方法名2( 参数列表2 ) 返回值列表2
    …
}

Go语言的接口在命名时,一般会在单词后面添加er,接口名最好要能突出该接口的类型含义。

Go语言的接口,是一种新的类型定义,它把所有的具有共性的方法定义在一起,任何其他类型只要实现了这些方法就是实现了这个接口。

4. 接口的实现

一个对象只要全部实现了接口中的方法,那么就实现了这个接口。

//定义一个Sayer接口
type Sayer interface {
    say()
}
 
type dog struct{}
 
type cat struct{}
 
//实现接口中具体的方法
func (d dog) say() {
    fmt.Println("狗:汪汪")
}
 
func (c cat) say() {
    fmt.Println("猫:喵喵")
}
 
func main() {
    d := dog{} //实例化结构体
    d.say()
    c := cat{}
    c.say()
}

注意:

  • 一个类型可以同时实现多个接口,而接口间彼此独立,不知道对方的实现。
  • Go语言中不同的类型可以实现同一个接口。

5. 接口的值类型和指针类型

这个本质上和方法的值类型接收和指针类型接收的思考方法是一样的,值接收是一个拷贝,是一个副本,而指针接收,传递的是指针。

定义一个Pet接口

type Pet interface {
    eat()
}

定义一个Dog结构体

type Dog struct {
    name string
}

实现Pet接口(接收者是值类型)

func (dog Dog) eat() {
    fmt.Printf("dog: %p\n", &dog)
    fmt.Println("dog eat..")
    dog.name = "黑黑"
}

运行示例:

func main() {
    dog := Dog{name: "花花"}
    fmt.Printf("dog: %p\n", &dog)
    dog.eat()
    fmt.Printf("dog: %v\n", dog)
}

运行结果:

dog: 0xc000046240
dog: 0xc000046250
dog eat..
dog: {花花}

从运行结果,我们看出dog的地址变了,说明是复制了一份,dogname没有变说明,外面的dog变量没有被改变。

Pet接口改为指针接收

func (dog *Dog) eat() {
    fmt.Printf("dog: %p\n", dog)
    fmt.Println("dog eat..")
    dog.name = "黑黑"
}

再次运行:

func main() {
    dog := &Dog{name: "花花"}
    fmt.Printf("dog: %p\n", dog)
    dog.eat()
    fmt.Printf("dog: %v\n", dog)
}

运行结果:

dog: 0xc00008c230
dog: 0xc00008c230
dog eat..
dog: &{黑黑}

6. 类型与接口关系

  • 一个类型可以实现多个接口
  • 多个类型可以实现同一个接口(多态)

下一篇我们继续探索 Go 语言接口的更多知识。

时间紧迫,Go语言的接口并不止这些,敬请期待:下一篇:接口(二)