Go的学习旅程4:面向接口

1.面向接口的简单实现

     因为go中没有class,只有结构体和方法,所以不存在class的继承与多态,但是我们可以通过interface来实现类似class的继承

1.1项目位置关系图

    

1.2各个文件中的代码

    queue.go  

package queue

import (
   "fmt"
   "strconv"
)

//这里有两个方法体
type Queue []int

type Human struct {
   Name  string
   Phone int
}

//添加队列
func (q *Queue) Push(a int) Queue {
   *q = append(*q, a)
   return *q
}

//消耗队列
func (q *Queue) Pop() int {
   a := (*q)[0]
   *q = (*q)[1:]
   return a
}

//介绍
func (h Human) SayHi() {
   fmt.Printf("Hi, I am %s you can call me on %s\n", h.Name, h.Phone)
}

//唱歌
func (h Human) Sing(lyrics string) {
   fmt.Println("La la la la...", lyrics)
}

//注意:输出的类型是string,那么phone就得转化为string
func (h Human) See(name string) string {
   return "我看到了你" + name + ",我的电话是:" + strconv.Itoa(h.Phone)
}

    rel.go

package queue

import (
   "strconv"
   "fmt"
)

type Dier struct {
   Name  string
   Phone int
}

func (d Dier) See(name string) string {
   return "我这个是老二,调用的name:" + name + "手机号码是:" + strconv.Itoa(d.Phone)
}

func (d Dier) SayHi(){
    fmt.Printf("你大舅他二舅,都是你:%d的舅",d.Name)
}

func (d Dier)Sing(lyrics string)  {
   fmt.Printf("你这唱的是??我唱的是:%d",lyrics)
}


main.go

package main

import (
   "fmt"
   "../../queue"
)

//通过接口,来继承SayHiSing(只能引用导入包其中的一个文件中,可以说是选择性的继承)
type Men interface {
   SayHi()
   Sing(lyrics string)
   See(name string) string
}

func diao(r Men) string {
   return r.See("四狗子")
}

func main() {
   q := queue.Queue{1, 2, 3, 4}
   fmt.Println(q.Push(5))
   fmt.Println(q.Pop())
   fmt.Println(q)

   //i继承了SayHiSing,直接调用
   var i Men
   i = queue.Human{"二狗子", 15888888888}
   i.SayHi()
   i.Sing("18岁的天空")
   fmt.Println(i.See("三狗子"))

   //通过函数,调用不同接口
   //调用第一种
   var r Men
   r=queue.Human{"二狗子", 19999999999}
   fmt.Println(diao(r))
   //调用第二种
   r=queue.Dier{"三狗子", 18888888888}
   fmt.Println(diao(r))

}
这里通过interface来调用SayHi(),See()和Sing()方法,这里被称为Men的隐藏字段(和class继承的道理是一样的)
type Men interface {                                           

   SayHi()
   Sing(lyrics string)
   See(name string) string
}

值得注意的是,因为Human和Dier中的方法是一样的,所以Men理论上是都可以继承的,但是需要在r赋值中声明

var r Men
   r=queue.Human{"二狗子", 19999999999}
   fmt.Println(diao(r))
   //调用第二种
   r=queue.Dier{"三狗子", 18888888888}
   fmt.Println(diao(r))


结果展示:



2.面向接口的组合调用

    因为go中也是可以同级调用,或外部调用的,效果如下

2.1项目位置关系图

    

1.2各个文件中的代码


jiben.go是该例子中最底层封装的结构体

package duo

import "strconv"

type Jb struct {
   Name   string
   Age    int
   Tel    int
   Phone  int
   Weight float64
}

func (j Jb) Jieshao() string {
   return "我叫" + j.Name + ",今年" + strconv.Itoa(j.Age) + ",我的电话是:"+strconv.Itoa(j.Tel)+"欢迎骚扰!"
}

func (j Jb) Mubiao(number int) string{
   return "我是"+j.Name+"我的体重是:"+strconv.FormatFloat(j.Weight,'g',5,64)+"我的目标是:"+strconv.Itoa(number)
}


study.go中的Student在jiben.go的基础上,调用了Jb参数并让Xx继承了Jieshao() string和Mubiao(number int) string函数

package duo

import (
   "strconv"
)

type Student struct {
   //调用Jb的基本信息(都是属于duo这个包,所以不需要import)
   Jb
   School string
   Money  int
}

type Xx interface {
   Jieshao() string
   Mubiao(number int) string
}

func (s Student) Jie() string {
   return "我是一个学生狗,我的学校是:" + s.School + ",我生活费是:" + strconv.Itoa(s.Money)
}

func (s Student) Zhen(num int) string {
   return "我想一月挣:" + strconv.Itoa(num) + ""
}

func (s Student) Zhu() string {
   //调用Jb下的Jieshao方法,同属于一个包不需要用import
   return s.Jieshao()
}


最后的main.go不仅让Ren继承Jieshao() string和Mubiao(number int) string,Xiao继承了Jie() string

,Zhen(num int) string和Zhu() string,而且使得Duo继承了Xiao,duo.Xx,必须主意的是,因为duo.Xx和Ren本质上是相同的,所以只需要引入一个即可;

package main

import (
   "fmt"
   "../../duo"
)
//继承Jb
type Ren interface {
   Jieshao() string
   Mubiao(number int) string
}
//继承Student
type Xiao interface {
   Jie() string
   Zhen(num int) string
   Zhu() string
}
//继承 Ren(duo.Xx)Xiao,因为Renduo.Xx是重复调用的,所以只能调其中的一个,不能多次调用
type Duo interface {
   Xiao
   duo.Xx
   //Ren
}

//调用者来申明接口
func main() {
   //调用自己
   var i Ren
   i = duo.Jb{"王二丫", 18, 8727444, 15888888888, 45.25}
   fmt.Println(i.Jieshao())
   fmt.Println(i.Mubiao(18))
   fmt.Println("王二丫结束")

   //调用外部
   var j Xiao
   //noinspection ALL
   j = duo.Student{duo.Jb{"李二柜",22,8457412,19999999999,80.8},"山西大学", 5000}
   fmt.Println(j.Jie())
   fmt.Println(j.Zhen(9999))
   fmt.Println(j.Zhu())
   fmt.Println("李二柜结束")

   //组合调用
   var w Duo
   w = duo.Student{duo.Jb{"罗二炮",30,7777777,17777777777,120},"理工大学", 6000}

   fmt.Println(w.Jieshao())
   fmt.Println(w.Jie())
   fmt.Println(w.Mubiao(30))

}

运行main.go

结果展示:







猜你喜欢

转载自blog.csdn.net/feiwutudou/article/details/80429253