前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Go语言入门(十一) 接口编程

Go语言入门(十一) 接口编程

作者头像
alexhuiwang
发布2020-09-24 16:47:26
6590
发布2020-09-24 16:47:26
举报
文章被收录于专栏:运维博客运维博客

接口

接口的定义

  • 接口定义了一个对象化的行为规范
    • 只定义规范,不实现
    • 具体的对象需要实现规范的细节
  • 实践
    • type 定义接口 interface
    • 接口里面是一组方法签名的集合
代码语言:javascript
复制
type Animal interface {
   Talk()
   Eat()
   Run()
}
  • 实现
    • 一个对象只要包含接口中的方法,那么就实现了这个接口
    • 接口类型的变量可以保存实现该接口的任何类型的实例
代码语言:javascript
复制
type Animal interface {
   Talk()
   Eat()
   Run()
}

type Dog struct {
   name string
}

//一个对象只要包含接口中的方法,那么就实现了这个接口
func (d *Dog) Eat() {
   fmt.Printf("%s is eating\n",d.name)
}

func (d *Dog) Talk() {
   fmt.Printf("%s is talking\n",d.name)
}

func (d *Dog) Run() {
   fmt.Printf("%s is running\n",d.name)
}

func main() {
   var dog = &Dog{
      name:  "旺财",
   }

   var a Animal
   //接口类型的变量可以保存实现该接口的任何类型的实例
   a = dog
   a.Eat()
   a.Run()
   a.Talk()
   fmt.Printf("a:%v,dog:%v\n",a,dog)
}

接口实例

  • 计算公司所有职员的薪水
  • 每个职员的计算方式不同
结构体实现
代码语言:javascript
复制
type Developer struct {
   Name   string
   Base   float64
}

func (d *Developer)Calc() float64{
   return d.Base
}

type PM struct {
   Name  string
   Base  float64
   Option float64
}

func (p *PM)Calc() float64{
   return p.Base + p.Option
}

type YY struct {
   Name string
   Base  float64
   Ratio float64
   Option float64
}

func (y *YY)Calc() float64 {
   return y.Base + y.Option * y.Ratio
}

type EmployeeMgr struct {
   devlist []*Developer
   pmlist []*PM
   yylist []*YY
}

func (e *EmployeeMgr)Calc() float64  {
   var sum float64
   for _,v := range e.devlist {
      sum += v.Calc()
   }

   for _,v1 := range e.pmlist {
      sum += v1.Calc()
   }

   for _,v2 := range e.yylist {
      sum += v2.Calc()
   }

   return sum
}

func (e *EmployeeMgr)AddDev(d *Developer) {
   e.devlist = append(e.devlist, d)
}

func (e *EmployeeMgr)AddPM(p *PM) {
   e.pmlist = append(e.pmlist, p)
}

func (e *EmployeeMgr)AddYY(y *YY) {
   e.yylist = append(e.yylist, y)
}

func main() {
   var e = &EmployeeMgr{}
   dev := &Developer{
      Name: "develop",
      Base: 5000,
   }
   e.AddDev(dev)

   pm := &PM{
      Name:   "pm",
      Base:   10000,
      Option: 2000,
   }
   e.AddPM(pm)

   yy := &YY{
      Name: "yy",
      Base: 23000,
      Option: 9000,
      Ratio: 0.67,
   }
   e.AddYY(yy)

   sum := e.Calc()
   fmt.Printf("sum:%.2f\n",sum)
}
接口实现
代码语言:javascript
复制
type Employee interface {
   Calc() float64     //接口返回
}

type Developer struct {
   Name   string
   Base   float64
}

func (d *Developer)Calc() float64{
   return d.Base
}

type PM struct {
   Name  string
   Base  float64
   Option float64
}

func (p *PM)Calc() float64{
   return p.Base + p.Option
}

type YY struct {
   Name string
   Base  float64
   Ratio float64
   Option float64
}

func (y *YY)Calc() float64 {
   return y.Base + y.Option * y.Ratio
}

type EmployeeMgr struct {
   employeelist []Employee
}

func (e *EmployeeMgr) Calc() float64 {
   var sum float64
   for _,v := range e.employeelist {
      sum += v.Calc()
   }
   return sum
}

func (e *EmployeeMgr) AddEmployee(d Employee) {
   e.employeelist = append(e.employeelist,d)
}

func main() {
   var e = &EmployeeMgr{}
   dev := &Developer{
      Name: "develop",
      Base: 5000,
   }
   e.AddEmployee(dev)

   pm := &PM{
      Name:   "pm",
      Base:   10000,
      Option: 2000,
   }
   e.AddEmployee(pm)

   yy := &YY{
      Name: "yy",
      Base: 23000,
      Option: 9000,
      Ratio: 0.67,
   }
   e.AddEmployee(yy)

   sum := e.Calc()
   fmt.Printf("sum:%.2f\n",sum)
}

空接口

  • 空接口没有定义任何方法
  • 所以了任何类型都实现了空接口
代码语言:javascript
复制
func main() {
   var a interface{}
   var b int
   a = b
   fmt.Printf("a=%v,a:%T\n",a,a)
   var c float64
   a = c
   fmt.Printf("a=%v,a:%T\n",a,a)
}

类型断言

  • 需要引入v,ok := i(T)机制
代码语言:javascript
复制
func Describe(a Animal) {
   /*代码有坑
   dog := a.(*Dog)
   dog.Eat()
    */
   dog,ok := a.(*Dog)
   if !ok {
      fmt.Printf("convert to dog error\n")
      return
   }
   fmt.Printf("describe dog succ\n")
   dog.Run()
   fmt.Printf("describe dog succ------\n")
}
  • 类型断言
代码语言:javascript
复制
func DescribeSwitch(a Animal) {
   fmt.Printf("DescribeSwitch(a) Begin\n")
   switch a.(type) {
   case *Dog:
      dog := a.(*Dog)
      dog.Run()
   case *Pig:
      pig := a.(*Pig)
      pig.Eat()
   }
   fmt.Printf("DescribeSwitch(a) End\n")
}
  • 类型断言改进版
代码语言:javascript
复制
func DescribeSwitch(a Animal) {
   fmt.Printf("DescribeSwitch(a) Begin\n")
   switch v:=a.(type) {
   case *Dog:
      dog := v
      dog.Run()
   case *Pig:
      pig := v
      pig.Eat()
   }
   fmt.Printf("DescribeSwitch(a) End\n")
}
  • 指针接收
  • 同一个类型可以实现多个接口
代码语言:javascript
复制
type Animal interface {
   Talk()
   Eat()
   Run()
}

type BuRuAnimal interface {
   ChiNai()
}

type Dog struct {
   name string
}

//一个对象只要包含接口中的方法,那么就实现了这个接口
func (d Dog) Eat() {
   fmt.Printf("%s is eating\n",d.name)
}

func (d Dog) Talk() {
   fmt.Printf("%s is talking\n",d.name)
}

func (d Dog) Run() {
   fmt.Printf("%s is running\n",d.name)
}

func (d Dog) ChiNai() {
   fmt.Printf("%s is chinai\n",d.name)
}

func main() {
   var dog = &Dog{
      name:  "旺财",
   }
   var a Animal
   //接口类型的变量可以保存实现该接口的任何类型的实例
   a = dog
   //Describe(a)
   //DescribeSwitch(a)
   a.Eat()
   var dogVar = Dog{name:"来福"}
   a = dogVar
   a.Run()
   //实现多个接口
  var b BuRuAnimal
  b = dog
  b.ChiNai()
}
  • 接口嵌套
代码语言:javascript
复制
type Animal interface {
   Talk()
   Eat()
   Run()
}

type BuRuAnimal interface {
   ChiNai()
}

type AdvanceAnimal interface {
   Animal
   BuRuAnimal
}

type Dog struct {
   name string
}

//一个对象只要包含接口中的方法,那么就实现了这个接口
func (d Dog) Eat() {
   fmt.Printf("%s is eating\n",d.name)
}

func (d Dog) Talk() {
   fmt.Printf("%s is talking\n",d.name)
}

func (d Dog) Run() {
   fmt.Printf("%s is running\n",d.name)
}

func (d Dog) ChiNai() {
   fmt.Printf("%s is chinai\n",d.name)
}

func main() {
   var dog = &Dog{
      name:  "旺财",
   }
   var a AdvanceAnimal
   a = dog
   a.ChiNai()
}

接口实例详解

  • io包中的writer接口
代码语言:javascript
复制
type Test struct {
   data string
}

func (t *Test)Write(p []byte) (n int,err error) {
   t.data = string(p)
   return len(p),nil
}

func FprintfDemo() {
   file,_ := os.Create("./a.txt")
   fmt.Fprintf(os.Stdout,"hello world\n")
   fmt.Fprintf(file,"hello World\n")   //终端文件写入

   var t *Test = &Test{}
   //将字符串写入内存,然后再读取
   fmt.Fprintf(t,"this is a test interface %s","dasdada")
   fmt.Printf("t.data=%s\n",t.data)

}
  • fmt包中的Stringer接口 返回字符串
代码语言:javascript
复制
type Student struct {
   Name string
   Age  int
}

func (s *Student)String()string {
   data,_ := json.Marshal(s)
   return string(data)
}

func main() {
   var s = &Student{
      Name: "ABC",
      Age: 22,
   }
   fmt.Printf("s = %v\n",s)
}
  • error接口
代码语言:javascript
复制
type MyError struct {
   When time.Time
   What string
}

func (e *MyError) Error()string{
   str:= fmt.Sprintf("time=%v,message=%s\n",e.When,e.What)
   fmt.Printf("1:%T\n",str)
   return str
}

func run()error {
   fmt.Printf("0\n")
   str:=MyError{time.Now(),"it did not work well"}
   fmt.Printf("2:%T\n",str)
   fmt.Printf("%v,%s\n",time.Now(),"error to run!!")
   return &str
}

func main() {
   if err := run();err!=nil {
      fmt.Printf("3:%T\n",err)
      fmt.Println(err)
   }
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-04-14 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 接口
    • 接口的定义
      • 接口实例
      • 空接口
      • 类型断言
    • 接口实例详解
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档