13-接口

什么是接口

接口就是一系列方法的集合

当一个结构体定义了接口中的所有方法,我们称它实现了该接口。这与面向对象编程(OOP)的说法很类似。接口指定了一个类型应该具有的方法,并由该类型决定如何实现这些方法

语法

type 接口名 interface{
    方法一
    方法二
}

接口的声明与实现

package main
import "fmt"

//定义一个鸭子接口(一系列方法的集合)
type Duck interface {
    run()
    speak()
}
//定义普通鸭子结构体(一系列属性的集合)
type PDuck struct {
    name string
    age int
}
//定义唐老鸭的结构体
type TDuck struct {
    name string
    age int
    wife bool
}

//实现run方法
func (p PDuck)run()  {
    fmt.Println(p.name,"我在走路")
}
//实现speak方法
func (p PDuck)speak()  {
    fmt.Println(p.name,"我在讲话")
}

//唐老鸭实现接口(实现两个方法)
func (T TDuck)run()  {
    fmt.Println(T.name,"我在走路")
}
func (T TDuck)speak()  {
    fmt.Println(T.name,"我在说话")
}
func main() { pD:
=PDuck{name:"水鸭子"} //结构体赋值 tD:=TDuck{name:"唐老鸭"} pD.speak() //实现接口方法 tD.speak() var p Duck //通过接口直接访问方法 p=pD p.speak() } #结果 水鸭子 我在讲话 唐老鸭 我在说话 水鸭子 我在讲话

类型断言

func speak(p Duck)  {
    switch a:=p.(type) {
    case PDuck:
        //判断好了,你是普通鸭子,把鸭子名字拿出来
        fmt.Println("你是普通鸭子")
        fmt.Println(a.name)
    case TDuck:
        //判断好了,你是唐老鸭,把唐老鸭的wife拿出来
        fmt.Println("你是唐老鸭")

        fmt.Println(a.wife)
    }
}

空接口

没有包含方法的接口称为空接口。空接口表示为 interface{}。由于空接口没有方法,因此所有类型都实现了空接口

package main
import "fmt"

type Empty interface {    //空接口

}
type TDuck2 struct {
    name string
    age string
    wife bool
}
func main() {
    test(1)
    test("ssss")
    test(TDuck2{})
    test(10.45)
}

func test(a interface{})  {  //因为test函数接收空接口作为参数,因此可以给这个函数传递任何类型。用interface{}接收空接口
    switch a.(type) {    //做断言判断
    case int:
        fmt.Println("你是int类型")
    case string:
        fmt.Println("你是string ")
    case TDuck2:
        fmt.Println("你是唐老鸭")
    default:
        fmt.Println("我不知道你是什么类型")

    }
}

实现多个接口

就是一个结构体实现多个接口的方法

package main
import (
    "fmt"
)

type SalaryCalculator interface {
    DisplaySalary()
}

type LeaveCalculator interface {
    CalculateLeavesLeft() int
}

type Employee struct {
    firstName string
    lastName string
    basicPay int
    pf int
    totalLeaves int
    leavesTaken int
}

func (e Employee) DisplaySalary() {
    fmt.Printf("%s %s has salary $%d", e.firstName, e.lastName, (e.basicPay + e.pf))
}

func (e Employee) CalculateLeavesLeft() int {
    return e.totalLeaves - e.leavesTaken
}

func main() {
    e := Employee {
        firstName: "Naveen",
        lastName: "Ramanathan",
        basicPay: 5000,
        pf: 200,
        totalLeaves: 30,
        leavesTaken: 5,
    }
    e.DisplaySalary()
    e.CalculateLeavesLeft()
    fmt.Println("\nLeaves left =", e.CalculateLeavesLeft())
    //除了上面可以直接用e.方法名获得,还可以按照下面这种写法
    //var s SalaryCalculator = e     //把e赋值给了SalaryCalculator类型的接口变量
    //s.DisplaySalary()           //然后调用DisplaySalary方法
    //var l LeaveCalculator = e      //把e赋值给了LeaveCalculator类型的接口变量
}
#结果
Naveen Ramanathan has salary $5200
Leaves left = 25

接口的嵌套

尽管 Go 语言没有提供继承机制,但可以通过嵌套其他的接口,创建一个新接口。

package main

import (  
    "fmt"
)

type SalaryCalculator interface {  
    DisplaySalary()
}

type LeaveCalculator interface {  
    CalculateLeavesLeft() int
}

type EmployeeOperations interface {   //嵌套了接口,就可以使用接口的方法
    SalaryCalculator
    LeaveCalculator
}

type Employee struct {  
    firstName string
    lastName string
    basicPay int
    pf int
    totalLeaves int
    leavesTaken int
}

func (e Employee) DisplaySalary() {  
    fmt.Printf("%s %s has salary $%d", e.firstName, e.lastName, (e.basicPay + e.pf))
}

func (e Employee) CalculateLeavesLeft() int {  
    return e.totalLeaves - e.leavesTaken
}

func main() {  
    e := Employee {
        firstName: "Naveen",
        lastName: "Ramanathan",
        basicPay: 5000,
        pf: 200,
        totalLeaves: 30,
        leavesTaken: 5,
    }
    var empOp EmployeeOperations = e
    empOp.DisplaySalary()
    fmt.Println("\nLeaves left =", empOp.CalculateLeavesLeft())
}
#结果
Naveen Ramanathan has salary $5200
Leaves left = 25

接口的零值

接口的零值nil,所以接口是引用类型

package main

import "fmt"

type Describer interface {  
    Describe()
}

func main() {  
    var d1 Describer
    if d1 == nil {
        fmt.Printf("d1 is nil and has type %T value %v\n", d1, d1)
    }
}
posted @ 2019-12-13 15:36  只会玩辅助  阅读(237)  评论(0编辑  收藏  举报