天天看点

Golang 接口笔记

基本介绍

接口是一个数据类型,可以定义一组方法,但都不需要实现。并且interface中不能包含任何变量。到某个自定义类型要使用的时候,再根据具体情况把这些方法实现出来

语法

type 接口名 interface {

method1(参数列表) 返回值列表

method2(参数列表) 返回值列表

}

说明:

  • 接口申明中所有的方法,都没有方法体,即接口中的方法都是没有实现的方法。接口体现了程序设计的多态和高内聚低耦合的思想
  • golang中的接口不需要显式的实现,只要一个变量含有接口类型中的所有方法,那么这个变量就实现了这个接口

入门示例

package main

import "fmt"

// 声明一个Usb接口
type Usb interface {
    Start()
    Stop()
}

// 定义一个手机结构体
type Phone struct {
}

// 手机结构体实现接口方法
func (p Phone) Start() {
    fmt.Println("手机开始工作...")
}
func (p Phone) Stop() {
    fmt.Println("手机停止工作...")
}

// 定义一个相机结构体
type Camera struct {
}

// 相机结构体实现接口方法
func (c Camera) Start() {
    fmt.Println("相机开始工作...")
}
func (c Camera) Stop() {
    fmt.Println("相机停止工作...")
}

// 定义一个电脑结构体
type Computer struct{}

// 电脑结构体绑定方法,接受Usb接口参数
func (c Computer) Working(usb Usb) {
    usb.Start()
    usb.Stop()
}

func main() {
    phone := Phone{}
    camera := Camera{}
    computer := Computer{}
    computer.Working(phone)
    computer.Working(camera)
}
           
Golang 接口笔记

接口细节

  • 接口本身不能创建实例,但是可以指向一个实现了该接口的自定义类型的变量
Golang 接口笔记
Golang 接口笔记
  • 接口中所有的方法都没有方法体
  • 在Golang中,一个自定义类型要实现某个接口,该自定义类型需要将接口的所有方法都实现
  • 一个自定义类型只有实现了某个接口,才能将该自定义类型的实例(变量)赋给给接口。案例详见1
  • 只要是自定义类型就可以实现接口,不仅仅是结构体类型
Golang 接口笔记
  • 一个自定义类型可以实现多个接口
package main

import "fmt"

// 定义接口AInterface
type AInterface interface {
    Hello()
}

// 定义解决BInterface
type BInterface interface {
    World()
}

// 定义结构体类型,同时实现接口AInterface、BInterface
type AStruct struct {
}

// 实现接口AInterface
func (a AStruct) Hello() {
    fmt.Println("Hello")
}

// 实现接口BInterface
func (a AStruct) World() {
    fmt.Println("World")
}

func main() {
    // a同时实现了接口AInterface、BInterface
    a := AStruct{}
    a.Hello()
    a.World()

    var ainterface AInterface
    ainterface = a
    ainterface.Hello() // AInterface只能调用自己定义的方法

    var binterface BInterface
    binterface = a
    binterface.World() // BInterface只能调自己定义的方法
}
           
Golang 接口笔记
  • 接口定义中不能有任何变量
Golang 接口笔记
  • 一个接口(比如A接口)可继承多个别的接口(比如B,C接口),这时要实现A接口,也必须将B,C接口的方法全部实现
package main

import "fmt"

type B interface {
    b()
}

type C interface {
    c()
}

// A接口继承了B,C接口
type A interface {
    B
    C
    a() // A接口自定义方法
}

type Stu struct{}

func (stu Stu) a() {
    fmt.Println("a")
}
func (stu Stu) b() {
    fmt.Println("b")
}
func (stu Stu) c() {
    fmt.Println("c")
}
func main() {
    stu := Stu{}
    stu.a()
    stu.b()
    stu.c()
    fmt.Println("-----------")
    var a A
    a = stu
    a.a()
    a.b()
    a.c()
}
           
Golang 接口笔记
  • interface类型默认是一个指针(引用类型),如果没有对interface初始化就使用,会输出nil
Golang 接口笔记
  • 空接口interface{}没有任何方法,所以所有类型都实现了空接口,即我们可以把任何一个变量赋给空接口
Golang 接口笔记

经典案例

// 接口的经典案例,使用sort.Sort对结构体切片进行排序
package main

import (
    "fmt"
    "math/rand"
    "sort"
)

// 定义学生结构体类型
type Student struct {
    Name string
    Age  int
}

// 定义学生切片
type StudentSlice []Student

// 实现Interface获取长度接口
func (s StudentSlice) Len() int {
    return len(s)
}

// 实现Interface接口,Less方法决定使用什么标准排序
// Less方法报告索引i的元素是否比索引j的元素小。i小为正序,i大为降序
func (s StudentSlice) Less(i, j int) bool {
    return s[i].Age < s[j].Age
}

// 实现Interface接口,Swap方法交换切换的数据
func (s StudentSlice) Swap(i, j int) {
    s[i], s[j] = s[j], s[i]
}

func main() {
    var studentSlice StudentSlice
    // 循环给学生切片追加数据
    for i := 0; i < 10; i++ {
        student := Student{
            Name: fmt.Sprintf("宋江_%d", rand.Intn(100)),
            Age:  rand.Intn(100),
        }
        studentSlice = append(studentSlice, student)
    }
    fmt.Println(studentSlice)
    fmt.Println("-----------排序后-----------")
    sort.Sort(studentSlice)
    fmt.Println(studentSlice)
}
           
Golang 接口笔记

继续阅读