32 Go 语言中的接口

在所有编程语言中,接口都是一些方法的集合,通常都是"类"们都需要实现的一些公共方法。使这些"类"在使用过程中多了一层抽象。在使用接口时无需在意这些方法是如何实现的,只需在意这个接口中的方法本身。Go 语言提倡面向接口编程,一来增强代码的可读性,二来可以使代码的模块之间的关系变得更加清晰、边界更加明显。本文就来介绍一下 Go 语言中的接口。

1. 接口定义

在 Go 语言中,接口也是一个数据类型,该类型使用结构 interface{...} 来定义。

代码示例:

var stuInterface interface{
    PrintAge()
}

以上代码定义可一个接口类型的变量,其中包含的方法为 PrintAge()。

2. 接口实现

了解了 Go 语言中接口的定义之后,我们来学习一下如何实现Go语言的接口。

在 Go 语言的接口中有两个非常重要的特性:

  • 只要有类实现(模拟)了接口中包含的所有方法,我们就称这个类型实现了这个接口
  • 只要是实现了这个接口的类型,用这个类型定义的变量就可以给这个接口声明的变量赋值

所以从以上两个特性也可以推出 interface{} 类型的变量,可以接收 任何变量的赋值。这两个特性也被称为鸭子类型,即"走起来像鸭子,叫起来像鸭子(类型模拟了接口中包含的所有方法),那么它就是一只鸭子"。

代码示例:

package main

import (
    "fmt"
)

var stuInterface interface {
    PrintAge()
}

type Student struct {
    Name string
    Age  int
}

func (s Student) PrintAge() {
    fmt.Println(s.Age)
}

func main() {
    stuInterface = Student{
        Name: "Codey",
        Age:  18,
    }
    stuInterface.PrintAge()
}
  • 第 21~24 行:定义了一个自定义类型,并且这个类型实现了接口变量类型中的方法;
  • 第 21 行:实例化一个自定义类型的变量,并赋值给这个接口变量;
  • 第 25 行:使用接口中的方法。会发现打印了学生的年龄。

执行结果:

图片描述

3. 自定义接口类型

为了方便使用,一般都会使用自定义类型来定义一个接口类型。同时还可以写一个函数来实例化接口。

代码示例:

package main

import (
    "fmt"
)

type StudentInterface interface {
    PrintAge()
}

type Student struct {
    Name string
    Age  int
}

func (s Student) PrintAge() {
    fmt.Println(s.Age)
}

func newStudent(name string, age int) StudentInterface {
    return Student{Name: name, Age: age}
}
func main() {
    stuInterface := newStudent("Codey", 18)

    stuInterface.PrintAge()
}
  • 第 20~22 行:定义一个函数来实例化接口;
  • 第 24 行:初始化一个接口变量。

执行结果:

图片描述

4. 小结

本文主要介绍了 Go 语言中接口的定义和使用。需要注意以下几点:

  • 在 Go 语言中接口是一个类型;
  • 一般使用自定义类型来定义接口;
  • Go 语言的接口是鸭子类型