Golang 接口

gopher Golang 48 次浏览 , 没有评论
package main

import "fmt"

// 定义一个接口
type Usb interface {
  // 声明两个没有实现的方法
  Start()
  Stop()
}

type Phone struct {

}

// 让Phone 实现Usb接口的方法
func (p Phone) Start()  {
  fmt.Println("手机开始工作。。。")
}

func (p Phone) Stop()  {
  fmt.Println("手机停止工作。。。")
}

type Camera struct {

}

// 让 Camera 实现Usb接口的方法
func (p Camera) Start()  {
  fmt.Println("相机开始工作。。。")
}

func (p Camera) Stop()  {
  fmt.Println("相机停止工作。。。")
}

// 计算机
type Computer struct {

}

// 编写一个方法 Working 方法,接收一个Usb接口类型的变量
// 只要实现了Usb 接口(所谓实现 Usb 接口,就是指实现了 Usb 接口声明所有方法)
func (c Computer) Working(usb Usb)  { // usb 变量会根据传入的实参,来判断到底是Phone,还是camera
  // 通过 usb 接口变量来调用 Start 和 Stop 方法
  usb.Start()
  usb.Stop()
}

func main()  {
  computer := Computer{}
  phone := Phone{}
  camera := Camera{}

  computer.Working(phone)
  computer.Working(camera)
}

说明

  1. 接口里的所有方法都没有方法体,即接口的方法都是没有实现的方法。接口体现了程序设计的多态和高内聚低耦合的思想。
  2. Golang中的接口,不需要显式的实现。只要一个变量,含有接口中的所有方法,那么这个变量就实现了这个接口。因此,Golang中没有implement这样的关键字

注意事项

  1. 接口本身不能创建实例,但是可以指向一个实现了该接口的自定义类型的变量
    package main
    
    import "fmt"
    
    type AInterface interface {
      Say()
    }
    
    type Student struct {
      Name string
    }
    
    func (s Student) Say()  {
      fmt.Println("Student say")
    }
    
    func main()  {
      student := Student{}
      var a AInterface = student
      a.Say()
    }

     

  2. 接口中所有的方法都没有方法体,即都是没有实现的方法。
  3. 在Golang中,一个自定义类型需要将某个接口的所有方法都实现,我们说这个自定义类型实现了该接口。
  4. 一个自定义类型只有实现了某个接口,才能将该自定义类型的实例赋给接口类型。
  5. 只要是自定义数据类型,就可以实现接口,不仅仅是结构体类型。
    package main
    
    import "fmt"
    
    type AInterface interface {
      Say()
    }
    
    type integer int
    
    func (i integer) Say()  {
      fmt.Println("Integer say i =", i)
    }
    
    func main()  {
      var i integer = 10
      var b AInterface = i
      b.Say()
    }

     

  6. 一个自定义类型可以实现多个接口
    package main
    
    import "fmt"
    
    type AInterface interface {
      Say()
    }
    
    type BInterface interface {
      Hello()
    }
    
    type Student struct {
      Name string
    }
    
    func (s Student) Say()  {
      fmt.Println("Student say")
    }
    
    func (s Student) Hello()  {
      fmt.Println("Student hello")
    }
    
    func main()  {
      student := Student{}
      var a AInterface = student
      var b BInterface = student
      a.Say()
      b.Hello()
    }

     

  7. Golang接口中不能有任何变量
  8. 一个接口(比如A接口)可以继承多个别的接口(比如B,C接口),这时如果要实现A接口,也必须将B,C接口的方法全部实现。
    package main
    
    import "fmt"
    
    type AInterface interface {
      test01()
    }
    
    type BInterface interface {
      test02()
    }
    
    type CInterface interface {
      AInterface
      BInterface
      test03()
    }
    
    // 如果要实现 CInterface ,就需要将AInterface 和 BInterface的所有方法
    type A struct {
    
    }
    
    func (a A) test01()  {
      fmt.Println("test01")
    }
    
    func (a A) test02()  {
      fmt.Println("test02")
    }
    
    func (a A) test03()  {
      fmt.Println("test03")
    }
    
    func main()  {
      var a A
      var c CInterface = a
      c.test01()
      c.test02()
      c.test03()
    }

     

  9. interface类型默认是一个指针(引用类型),如果没有对interface初始化使用,那么会输出nil
  10. 空接口interface{} 没有任何方法,所以所有类型都实现了空接口,即我们可以把任何一个变量赋给空接口。

接口最佳实践

package main

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

type Person struct {
  Name string
  Age int
}

type Slice []Person

func (s Slice) Len() int {
  return len(s)
}

func (s Slice) Less(i, j int) bool {
  return s[i].Age < s[j].Age
}

func (s Slice) Swap(i, j int) {
  s[i], s[j] = s[j], s[i]
}

func main()  {
  var slice Slice
  for i := 0; i < 10; i++ {
    person := Person{
      Name: "姓名—" + strconv.Itoa(rand.Intn(100)),
      Age: rand.Intn(100),
    }
    slice = append(slice, person)
  }
  for _, v := range slice {
    fmt.Println(v)
  }

  fmt.Println("---------排序之后------------")
  sort.Sort(slice)
  for _, v := range slice {
    fmt.Println(v)
  }
}

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注

Go