玩转Go语言之接口

604 阅读5分钟

代码:

github.com/codeXiaoQia…

1.接口的基本使用:

//定义一个接口
type Usb interface {
   start(name string)
   end(name string)
}

//定义一个结构体类型
type Computer struct {

}

// 实现接口中声明的方法
func (Computer)start(name string)  {
   fmt.Println(name, "启动了")
}
func (Computer)end(name string)  {
   fmt.Println(name, "关闭了")
}

type Phone struct {

}

// 实现接口中声明的方法
func (Phone)start(name string)  {
   fmt.Println(name, "启动了")
}
func (Phone)end(name string)  {
   fmt.Println(name, "关闭了")
}


func main() {

   //定义一个结构体变量
   cm := Computer{}

   //定义一个接口变量
   var in Usb

   //接口变量保存数据类型
   in = cm

   //通过接口变量使用接口中的函数
   in.start("电脑")
   in.end("电脑")

   //定义一个结构体变量
   ph := Phone{}

   //定义一个接口变量
   var inP Usb

   //接口变量保存数据类型
   inP = ph

   //通过接口变量使用接口中的
   inP.start("手机")
   inP.end("手机")

   option(in , "china")
   option(inP,"美国")
}

//实现一个公用的函数,只要传入品牌名称和接口

func option(in Usb,name string)  {
      in.start(name)
      in.end(name)
}

总结:

1.什么是接口?
Go语言中的接口和现实生活中的USB3.0接口很像, 用于定义某种规范
现实生活中, 只要生产厂家按照USB3.0接口的标准来生产, 那么无论什么品牌的电脑, 都可以使用
Go语言中, 只要使用者按照我们接口定义的标准来实现, 那么无论谁实现的我们都可以使用

2.接口的作用?
在Go语言中, 接口专门用于定义函数的声明
也就是规定函数的形参, 函数的返回值, 函数的名称

3.定义接口的格式:
type 接口的名称 interface{
   函数的声明
}

4.注意点:
4.1接口是虚的, 只有方法的声明, 没有方法的实现 (就和制定USB3.0标准的组织一样, 只负责制定标准, 不负责生产)
4.2接口中声明的方法, 只能通过和某种数据类型绑定的方法来实现, 不能通过函数来实现 (就和现实生活中只能由富士康, 等具备生产能力的公司来生成一样, 这里和和某种数据类型绑定的方法就是局部生产能力的公司, 函数就是不具备生产能力的公司)
4.3在Go语言中, 只要某个数据类型实现了接口中声明的`所有`方法, 那么就说这个数据类型实现了这个接口
4.4只要一个数据类型实现了某个接口, 那么就可以使用这个接口类型的变量来保存这个类型的数据
4.5只要一个数据类型实现了某个接口, 那么保存这个类型的数据之后, 就可以使用接口类型变量调用接口中的方法

2.接口注意点:

/*
//type USB interface {
// start() // 方法的声明
// // 下面的代码会报错
// func end(){ // 方法的实现
//    fmt.Println("end")
// }
//}
*/
/*
//type USB interface {
// start() // 方法的声明
// // 下面的代码会报错
// name string // 声明一个变量
//}
*/
/*
// 1.定义一个接口, 声明两个方法
type USB interface {
   start()
   end()
}

type Phone struct {

}
// 以下代码并没有实现接口中的方法
//func (Phone)start(name string)  {
// fmt.Println("启动")
//}
func (Phone)start()  {
   fmt.Println("启动")
}
func (Phone)end()  {
   fmt.Println("启动")
}
*/

/*
// 子集接口
type aer interface {
   //aer // 会报错
   start()
}
// 超集接口
type ber interface {
   aer // 在ber接口中嵌套了aer接口
   end()
}
type Phone struct {
   name string
}
// Phone这个结构体实现了aer接口的所有方法
// Phone此刻只实现了ber接口的一个方法
//func (p Phone)start()  {
// fmt.Println(p.name, "启动了")
//}
//  Phone这个结构体实现了aer接口的所有方法
//  Phone这个结构体实现了ber接口的所有方法
func (p Phone)start()  {
   fmt.Println(p.name, "启动了")
}
func (p Phone)end()  {
   fmt.Println(p.name, "停止了")
}
*/

type USB interface {
   start()
   //start() // 会报错
}
type CMD interface {
   USB
   //start() // 会报错
}

func main() {
   /*
   注意点:
   1.接口中只能有方法的声明, 不能有方法的实现
   2.接口中只能有方法的声明, 不能有变量的声明
   3.只有实现了接口中声明的所有方法, 才算实现了接口, 才能使用接口变量保存
   4.在实现接口的时候, 方法名称,形参列表,返回值列表必须一模一样
   5.接口和结构体一样, 可以嵌套
   6.接口和结构体一样, 嵌套时不能嵌套自己(自己搞自己)
   7.可以将集接口变量赋值给子集接口变量,不可以将子集接口变量赋值给超集接口变量(无论实际的数据类型是否已经实现了超集的所有方法)
   8.接口中不能出现同名的方法声明
    */

    //var in USB = Phone{}
    //fmt.Println(in)

    /*
    //var in aer = Phone{"华为"}
    //var in ber = Phone{"华为"}
    //in.start()

   // // 1.用超集接口变量保存结构体
   //var b ber = Phone{"华为"}
   //// 2.将超集接口变量赋值给子集接口变量
   //var a aer
   //a = b
   //a.start()

   // 1.用子集接口变量保存结构体
   var a aer = Phone{"华为"}
   // 2.将子集接口变量赋值给超集接口变量
   var b ber
   b = a // 会报错
   b.start()
    */
}

3.空接口:

type Person struct {
   name string
   age  int
}

func main() {
   /*
    1.什么是空接口?
   Go语言中的空接口, 相当于其他语言的Object类型
   Go语言中的空接口, 可以充当任何类型

   2.空接口类型的格式
   interface{}

   3.正式因为有了空接口类型, 所以也可以让数组和字典保存不同类型的数据
   面试回答: 数组和字典一般用于保存相同类型的数据, 而结构体用于保存不同类型的数据
             但是也可以通过空接口类型来实现让数组和字典保存不同类型的数据

   注意点: 空接口类型和普通的数据类型, 在使用的时候还是有很大区别的
    */
    /*
   // 1.定义一个空接口类型变量
   var value interface{}
   value = 1 // 保存整型
   fmt.Println(value)
   value = 3.14 // 保存浮点类型
   fmt.Println(value)
   value = false // 保存布尔类型
   fmt.Println(value)
   value = 'T' // 保存字符
   fmt.Println(value)
   value = "lnj" // 保存字符串类型
   fmt.Println(value)
   value = [3]int{1, 3, 5} // 保存数组类型
   fmt.Println(value)
   value = []int{2, 4, 5} // 保存切片类型
   fmt.Println(value)
   value = map[string]string{"name": "lnj", "age": "18"} // 保存字典类型
   fmt.Println(value)
   value = Person{"lnj", 33} // 保存结构体类型
   fmt.Println(value)
    */


    // 1.定义一个数组
    var arr [3]interface{}
    // 2.往数组中存储数据
    arr[0] = 1
    arr[1] = "lnj"
    arr[2] = false
    // 3.打印数据
    fmt.Println(arr)
}