zoukankan      html  css  js  c++  java
  • Go语言接口

    接口介绍

    在Go语言中接口(interface)是一种类型,一种抽象的类型。

    接口的定义

    定义格式:

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

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

    接口实现

    一个对象只要全部实现了接口中的方法,那么就实现了这个接口。
    Go语言中不同的类型可以实现同一个接口。(示例中dog和cat都实现了Animal接口)

    //定义一个Animal接口
    // Animal 是一个动物接口,实现move()和say()方法
    type Animal interface {
        move()
        say()
    }
    
    //定义dog结构体
    type dog struct {
        name string
    }
    //定义cat结构体
    type cat struct {
        name string
    }
    //dog实现move方法
    func (d dog) move() {
        fmt.Printf("%s会跑
    ",d.name)
    }
    //dog实现say方法
    func (d dog) say() {
        fmt.Printf("%s会叫汪汪汪
    ",d.name)
    }
    //cat实现move方法
    func (c *cat) move() {
        fmt.Printf("%s会跑
    ",c.name)
    }
    //cat实现say方法
    func (c cat) say() {
        fmt.Printf("%s会叫喵喵喵
    ",c.name)
    }
    func main()  {
        var a Animal    //声明一个Animal类型的a
        //实例化一个dog结构体
        d := dog{name:"旺财"}
        fmt.Printf("%T
    ", d)       //main.dog
        d.move()    //旺财会跑
        d.say()     //旺财会叫汪汪汪
        a = d // 接口是一种类型,一种抽象的类型。
        fmt.Println(a)  //{旺财}
        //实例化一个cat结构体
        c := cat{name:"蓝猫"}
        c.move()    //蓝猫会跑
        c.say()     //蓝猫会叫喵喵喵
    }
    

    多态

    GO语言通过接口模拟多态。

    类型与接口关系

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

    接口嵌套

    接口与接口间可以通过嵌套创造出新的接口。

    //定义speaker接口
    type speaker interface {
        speak()
    }
    //定义mover接口
    type mover interface {
        move()
    }
    // 接口嵌套
    type animal interface {
        speaker
        mover
    }
    //定义cat结构体
    type cat struct {
        name string
    }
    //cat是值类型接收者
    func (c cat) speak() {
        fmt.Println("喵喵喵")
    }
    
    func (c cat) move() {
        fmt.Println("猫会动")
    }
    func main()  {
        var x animal
        x = cat{name: "花花"}
        x.move()    //猫会动
        x.speak()   //喵喵喵
    }
    

    空接口

    空接口定义

    空接口是指没有定义任何方法的接口。空接口类型的变量可以存储任意类型的变量。

    //空接口
    func main()  {
        var x interface{}
        x = 100     //int类型
        fmt.Println(x)  //100
        x = "ares"  //string类型
        fmt.Println(x)  //ares
        x = struct {    //结构体类型
            name string
        }{name:"ares"}  
        fmt.Println(x)  //ares
    }
    

    空接口应用

    空接口可以作为函数的参数或map的值。

    //空接口
    func showType(a interface{}) {
        fmt.Printf("type:%T
    ", a)
    }
    
    func main()  {
        //空接口作为函数的参数
        showType(100)       //type:int
        showType("ares")    //type:string
        //定义一个值为空接口的map
        var stu = make(map[string]interface{},100)
        stu["ares"] = 100
        stu["ares1"] = "男"
        fmt.Println(stu)    //map[ares:100 ares1:男]
        //map,key是字符串,value是任意类型
        map1 := make(map[string]interface{})
        map1["name"] = "ares"
        map1["age"] = 18
        map1["id"] = 1
        map1["friend"] = struct {
            name string
            age  int
        }{"jay", 33}
        fmt.Println(map1) //map[age:18 friend:{jay 33} id:1 name:ares]
        }
    

    接口嵌套

    类似于继承。

    type A interface {
        test1()
    }
    type B interface {
        test2()
    }
    type C interface {
        A
        B
        test3()
    }
    type Cat struct { //如果要实现接口c,需要将接口a和接口b中的方法一起实现
    }
    
    func (c Cat) test1() {
        fmt.Println("test1...")
    }
    func (c Cat) test2() {
        fmt.Println("test2...")
    }
    func (c Cat) test3() {
        fmt.Println("test3...")
    }
    func main() {
        var cat = Cat{}
        cat.test1() //test1...
        cat.test2() //test2...
        cat.test3() //test3...
        //将cat赋值接口A类型,则只能使用test1方法
        var cat1 A = Cat{}
        cat1.test1() //test1...
        //将cat赋值接口B类型,则只能使用test2方法
        var cat2 B = Cat{}
        cat2.test2() //test2...
    }
    

    类型断言

    语法:

    x.(T)
    

    x:表示类型为interface{}的变量
    T:表示断言x可能是的类型
    若为true则表示断言成功,为false则表示断言失败。

    //类型断言
    func justifyType(x interface{}) {
        switch v := x.(type) {
        case string:
            fmt.Printf("x is a string,value is %v
    ", v)
        case int:
            fmt.Printf("x is a int is %v
    ", v)
        case bool:
            fmt.Printf("x is a bool is %v
    ", v)
        case *string:
            fmt.Printf("x is a point指针 is %v
    ", v)
        case struct{}:
            fmt.Printf("x is a struct is %v
    ", v)
        default:
            fmt.Println("unsupport type!")
        }
    }
    func main()  {
        justifyType(100)        //x is a int is 100
        justifyType("ares") //x is a string,value is ares
        justifyType(false)  //x is a bool is false
        x := "ares"
        justifyType(&x) //x is a point指针 is 0xc000094010
        justifyType(struct {}{})    //x is a struct is {}
        justifyType([]int{123}) //unsupport type!
    }
    

    值接收者和指针接收者实现接口的区别

    如果接收者为指针类型的话,不能把值传进去。

    //定义animal接口
    type animal interface {
        speak()
        move()
    }
    //定义cat结构体
    type cat struct{
        name string
    }
    //定义dog结构体
    type dog struct{
        name string
    }
    //值接收者
     func (c cat) speak() {
        fmt.Printf("%s会叫喵喵喵
    ",c.name)
     }
     func (c cat) move() {
        fmt.Printf("%s会动
    ",c.name)
     }
     //指针接收者
    func (d *dog) speak() {
        fmt.Printf("%s会叫汪汪汪
    ",d.name)
    }
    func (d *dog) move() {
        fmt.Printf("%s会动
    ",d.name)
    }
    func main()  {
        var c1 animal
        lm := cat{name:"蓝猫"}
        c1 = lm     //因为实现animal接口的是cat值类型,所以可以直接赋值
        c1.move()   //蓝猫会动
        c1.speak()  //蓝猫会叫喵喵喵
        var c2 animal
        jm := &dog{name:"金毛"}   //现animal接口的是*dog类型,所以必须要通过&来取值
        c2 = jm
        c2.move()   //金毛会动
        c2.speak()  //金毛会叫汪汪汪
    }
    
  • 相关阅读:
    肥胖儿筛选标准
    文章索引
    面向对象66原则
    [精]Xpath路径表达式
    [精]XPath入门教程
    孕产期高危因素
    “华而不实”的转盘菜单(pie menu)
    xmind用例导excel用例,然后再用python排版
    NSObject
    [self class]与[super class]
  • 原文地址:https://www.cnblogs.com/aresxin/p/Go-yu-yan-jie-kou.html
Copyright © 2011-2022 走看看