GO:interface

一、感受接口

type Usb interface {
    Connect()
    Disconnect()
}
// 手机
type Phone struct {}
// 相机
type Camera struct {}
// 计算机
type Computer struct {}
// 手机实现接口所有方法
func (p Phone) Connect() {
    fmt.Println("手机连接中...")
}
func (p Phone) Disconnect() {
    fmt.Println("手机断开连接中...")
}
// 相机实现接口所有方法
func (c Camera) Connect() {
    fmt.Println("相机连接中...")
}
func (c Camera) Disconnect() {
    fmt.Println("相机断开连接中...")
}
// Working方法,接收一个Usb接口类型变量
func (c Computer) Working(usb Usb) {
    // 通过接口变量来调用Connect和Disconnect方法
    usb.Connect()
    usb.Disconnect()
}
func main() {
    // 创建结构体实例
    phone := Phone{}
    camera := Camera{}
    computer := Computer{}
    // 关键点
    computer.Working(phone)
    computer.Working(camera)
}
// 输出如下
// 手机连接中...
// 手机断开连接中...
// 相机连接中...
// 相机断开连接中...
View Code

当传入一个phone,usb就能识别是手机,传入camera,usb就能识别是相机,并别分调用其相应的方法。这很明显就是多态呀!!!

func (c Computer) Working(usb Usb) {
	usb.Connect()
	usb.Disconnect()
}
func main() {
	phone := Phone{}
	camera := Camera{}
	computer := Computer{}
	computer.Working(phone)
	computer.Working(camera)
}

二、接口介绍

interface 类型可以定义一组方法,但是这些方法不需要实现。只要一个变量,含有接口类型中的所有方法,那么这个变量就实现了这个接口。

语法:

type 接口名 interface {
	method1(参数列表) 返回值列表
	method2(参数列表) 返回值列表
	...
}

三、注意事项和细节

  1. 接口本身不能创建实例,但是可以指向一个实现了该接口的自定义类型的实例;
  2. 接口中所有的方法都没有方法体,即只定义方法,没有实现该方法;
  3. 一个自定义类型只有实现了某个接口,才能将该自定义类型的实例赋给该接口类型;
  4. 只要是自定义数据类型,就可以实现接口,不仅仅是结构体类型;
  5. 一个自定义类型可以实现多个接口;
  6. golang的接口不能有任何变量;
  7. 一个接口(比如 C 接口)可以继承多个别的接口(比如 A、B 接口),这时如果要实现 C 接口,也必须将 A、B 接口中的方法也实现;注意,A、B接口中不能有相同的方法,相当于 C 接口有两个相同的方法,这是不允许的;
  8. interface 类型默认是一个指针(引用类型),如果没有对 interface 初始化就使用,那么会输出 nil ;
  9. 空接口 interface{} 没有任何方法,因此所有类型都实现了空接口,即可以把任何一个变量赋给空接口
  10. 如果一个自定义类型是使用指针方式实现一个接口的,那么需要将该自定义类型的地址赋给该接口,不然会报错。
type AInterface interface {
    Eat()
}

type Person struct {
    Name string
}

func (p Person) Eat() {
    fmt.Printf("%s正在吃饭...\n", p.Name) // 佩奇正在吃饭...
}

func main() {
    p := Person{"佩奇"}
    var a AInterface = p // 接口可以指向一个实现了该接口的自定义类型实例
    a.Eat()
}
第1、3点
type AInterface interface {
    Eat()
}

type BInterface interface {
    Sleep()
}

type Person struct {
    Name string
}

func (p Person) Eat() {
    fmt.Printf("%s正在吃饭...\n", p.Name) // 佩奇正在吃饭...
}

func (p Person) Sleep() {
    fmt.Printf("%s正在睡觉...\n", p.Name) // 佩奇正在睡觉...
}

func main() {
    p := Person{"佩奇"}
    var a AInterface = p
    var b BInterface = p
    a.Eat()
    b.Sleep()
}
第5点
type AInterface interface {
    Eat()
}

type BInterface interface {
    Sleep()
}

type CInterface interface {
    AInterface
    BInterface
    Study()
}

type Person struct {
    Name string
}

func (p Person) Eat() {
    fmt.Printf("%s正在吃饭...\n", p.Name) // 佩奇正在吃饭...
}

func (p Person) Sleep() {
    fmt.Printf("%s正在睡觉...\n", p.Name) // 佩奇正在吃饭...
}

func (p Person) Study() {
    fmt.Printf("%s正在学习...\n", p.Name) // 佩奇正在学习...
}

func main() {
    p := Person{"佩奇"}
    var c CInterface = p
    c.Eat()
    c.Sleep()
    c.Study()
}
第7点
type T interface {}

type Integer int

func main() {
    var int1 Integer
    int2 := Integer(100)
    var t T
    t = int1
    fmt.Println(t) // 0
    t = int2
    fmt.Println(t) // 100
}
第9点
type A interface {
    Eat()
}

type Person struct {
    Name string
}

// 使用 Person 指针类型实现一个接口的方法
func (p *Person) Eat() {
    fmt.Printf("%s正在吃饭...", p.Name)
}

func main() {
    p := Person{"佩奇"}
    //var a A = p // 错误!!!因为Person类型没有实现A接口,修改如下
    var a A = &p
    a.Eat()
}
第10点

四、接口最佳实践

实现对 Person 结构体切片的排序:sort.Sort(data Interface)

package main

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

type Person struct {
    Name string
    Age int
}

type PersonSlice []Person

func (ps PersonSlice) Len() int {
    return len(ps)
}
// Less方法决定使用什么标准进行排序
// 这里按年龄从小到大排序
func (ps PersonSlice) Less(i, j int) bool {
    return ps[i].Age < ps[j].Age
}
func (ps PersonSlice) Swap(i, j int) {
    ps[i], ps[j] = ps[j], ps[i]
}

func main() {
    var ps PersonSlice
    rand.Seed(time.Now().UnixNano())
    for i := 0; i < 10; i++ {
        person := Person{
            Name: fmt.Sprintf("无名%d号", i),
            Age: rand.Intn(100),
        }
        ps = append(ps, person)
    }
    // 排序前的顺序
    for _, v := range ps {
        fmt.Println(v)
    }
    // 调用sort.Sort方法
    sort.Sort(ps)
    fmt.Println()
    // 排序后的顺序
    for _, v := range ps {
        fmt.Println(v)
    }
}
View Code

输出结果:

2

猜你喜欢

转载自www.cnblogs.com/believepd/p/10940226.html