脚本之家,脚本语言编程技术及教程分享平台!
分类导航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服务器之家 - 脚本之家 - Golang - go语言interface接口继承多态示例及定义解析

go语言interface接口继承多态示例及定义解析

2022-09-19 16:45Jeff的技术栈 Golang

这篇文章主要为大家介绍了go语言interface接口继承多态示例及定义解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步早日升职加薪

1.什么是接口

接口就是一种规范与标准,在生活中经常见接口,例如:笔记本电脑的USB接口,可以将任何厂商生产的鼠标与键盘,与电脑进行链接。为什么呢?原因就是,USB接口将规范和标准制定好后,各个生产厂商可以按照该标准生产鼠标和键盘就可以了。

在程序开发中,接口只是规定了要做哪些事情,干什么。具体怎么做,接口是不管的。这和生活中接口的案例也很相似,例如:USB接口,只是规定了标准,但是不关心具体鼠标与键盘是怎样按照标准生产的.

在企业开发中,如果一个项目比较庞大,那么就需要一个能理清所有业务的架构师来定义一些主要的接口,这些接口告诉开发人员你需要实现那些功能。

2.接口定义

接口定义的语法如下:

?
1
2
3
4
5
6
7
8
方式一:interface接收任意数据格式
//先定义接口  一般以er结尾  根据接口实现功能
type CurrencyEr2 interface{
    Symbol() string
}
 
方式二:指定类型
type Currency string

怎样具体实现接口中定义的方法呢?

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
func (c Currency)Symbol() string {
    m := ""
    switch c {
    case "CNY":
        // 人民币
        m = "¥"
    case "KRW":
        // 韩币
        m = "₩"
    case "TWD":
        // 台币
        m = "$"
    case "JPY":
        // 日元
        m = "¥"
    case "USD":
        // 美元
        m = "$"
    }
    return m
}

具体的调用如下:

?
1
2
3
4
5
6
7
8
func main() {
  // 方式一:
  a:=CurrencyEr2(Currency("CNY")).Symbol()
    fmt.Println(a)
  // 方式二:
    b:=Currency("CNY").Symbol()
    fmt.Println(b)
}

只要类(结构体)实现对应的接口,那么根据该类创建的对象,可以赋值给对应的接口类型。

接口的命名习惯以er结尾。

3.多态

接口有什么好处呢?实现多态。

多态就是同一个接口,使用不同的实例而执行不同操作

所谓多态指的是多种表现形式,如下图所示:

使用接口实现多态的方式如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package main
import "fmt"
//先定义接口  一般以er结尾  根据接口实现功能
type CurrencyEr2 interface {
    //方法  方法的声明
    Symbol() string
}
type Currency string
type Currency2 string
func (c Currency) Symbol() string {
    m := ""
    switch c {
    case "CNY":
        m = "¥"
    }
    return m
}
func (c Currency2) Symbol() string {
    m := ""
    switch c {
    case "USD":
        m = "$"
    }
    return m
}
//多态的实现
//将接口作为函数参数  实现多态
func Start(c CurrencyEr2) string {
    return c.Symbol()
}
func main() {
    //调用多态函数
    a := Start(Currency("CNY"))
    fmt.Println(a)
    //调用多态函数
    b := Start(Currency2("USD"))
    fmt.Println(b)
}

多态加减计算器

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
package main
import "fmt"
//定义接口
type Opter interface {
    //方法声明
    Result() int
}
//父类结构体
type Operate struct {
    num1 int
    num2 int
}
//加法子类结构体
type Add struct {
    Operate
}
//实现加法子类的方法
func (a *Add) Result() int {
    return a.num1 + a.num2
}
//减法子类结构体
type Sub struct {
    Operate
}
//实现减法子类的方法
func (s *Sub) Result() int {
    return s.num1 - s.num2
}
//创建一个类负责对象创建
//工厂类
type Factory struct {
}
func (f *Factory) Result(num1 int, num2 int, ch string) int {
    sum := 0
    switch ch {
    case "+":
        var a Add
        a.num1 = num1
        a.num2 = num2
        sum = Opter.Result(&a)
    case "-":
        var s Sub
        s.num1 = num1
        s.num2 = num2
        sum = Opter.Result(&s)
    }
    return sum
}
//通过设计模式调用
func main() {
    //创建工厂对象
    var f Factory
    a:= f.Result(10, 20, "+")
    fmt.Println(a)
}

4.接口继承与转换

接口也可以实现继承:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package main
import "fmt"
//先定义接口  一般以er结尾  根据接口实现功能
type Humaner2 interface {   //子集
    //方法  方法的声明
    sayhi()
}
type Personer interface //超集
    Humaner2   //继承sayhi()
 
    sing(string)
}
type student13 struct {
    name  string
    age   int
    score int
}
func (s *student13)sayhi()  {
    fmt.Printf("大家好,我是%s,今年%d岁,我的成绩%d分\n",s.name,s.age,s.score)
}
func (s *student13)sing(name string)  {
    fmt.Println("我为大家唱首歌",name)
}
func main() {
    //接口类型变量定义
    var h Humaner2
    var stu student13 = student13{"小吴",18,59}
    h = &stu
    h.sayhi()
    //接口类型变量定义
    var p Personer
    p = &stu
    p.sayhi()
    p.sing("大碗面")
}

接口继承后,可以实现“超集”接口转换“子集”接口,代码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package main
import "fmt"
//先定义接口  一般以er结尾  根据接口实现功能
type Humaner2 interface {   //子集
    //方法  方法的声明
    sayhi()
}
type Personer interface //超集
    Humaner2   //继承sayhi()
    sing(string)
}
type student13 struct {
    name  string
    age   int
    score int
}
func (s *student13)sayhi()  {
    fmt.Printf("大家好,我是%s,今年%d岁,我的成绩%d分\n",s.name,s.age,s.score)
}
func (s *student13)sing(name string)  {
    fmt.Println("我为大家唱首歌",name)
}
func main()  {
    //接口类型变量定义
    var h Humaner2  //子集
    var p Personer    //超集
    var stu student13 = student13{"小吴",18,59}
    p = &stu
    //将一个接口赋值给另一个接口
    //超集中包含所有子集的方法
    h = p  //ok
    h.sayhi()
    //子集不包含超集
    //不能将子集赋值给超集
    //p = h  //err
    //p.sayhi()
    //p.sing("大碗面")
}

5.空接口

空接口(interface{})不包含任何的方法,正因为如此,所有的类型都实现了空接口,因此空接口可以存储任意类型的数值。

例如:

?
1
2
3
4
5
6
7
var i interface{}
//接口类型可以接收任意类型的数据
//fmt.Println(i)
fmt.Printf("%T\n",i)
i = 10
fmt.Println(i)
fmt.Printf("%T\n",i)

当函数可以接受任意的对象实例时,我们会将其声明为interface{},最典型的例子是标准库fmt中PrintXXX系列的函数,例如:

?
1
2
func Printf(fmt string, args ...interface{})
func Println(args ...interface{})

如果自己定义函数,可以如下:

?
1
2
func Test(arg ...interface{}) {
}

Test( )函数可以接收任意个数,任意类型的参数。

6.接口转换

结论:超集可以转换为子集,子集不可以转换为超集

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package main
import "fmt"
type Humaner interface { //子集
    sayhi()
}
type Personer interface { //超集
    Humaner //匿名字段,继承了sayhi()
    sing(lrc string)
}
type Student struct {
    name string
    id   int
}
//Student实现了sayhi()
func (tmp *Student) sayhi() {
    fmt.Printf("Student[%s, %d] sayhi\n", tmp.name, tmp.id)
}
func (tmp *Student) sing(lrc string) {
    fmt.Println("Student在唱着:", lrc)
}
func main() {
    //超集可以转换为子集,反过来不可以
    var iPro Personer //超集
    iPro = &Student{"mike", 666}
    var i Humaner //子集
    //iPro = i //err
    i = iPro //可以,超集可以转换为子集
    i.sayhi()
}

7.实现map字典接口

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package main
import (
    "fmt"
    "sync"
)
type UserAges struct {
    ages map[string] int
    sync.Mutex
}
func (u *UserAges)Add(name string,age int)  {
    u.Lock()
    defer u.Unlock()
    u.ages[name] = age
}
func (u *UserAges)Get(name string)int{
    if age,ok:=u.ages[name];ok{
        return age
    }
    return -1
}
func main() {
    dic:=make(map[string]int)
    dic["age"] = 18
    r:=UserAges{ages: dic}
    r.Add("jeff",20)
    fmt.Println(r)
    age:=r.Get("age")
    fmt.Println(age)
}

8.interface案例

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package main
import "fmt"
type Bike interface {
    save()
    update()
    insert()
}
type User struct {
    name string
}
func (this *User) save() {
    fmt.Println("保存成功", this.name)
}
func (this *User) update() {
    fmt.Println("更新成功", this.name)
}
func (this *User) insert() {
    fmt.Println("插入成功", this.name)
}
func main() {
    var data Bike = &User{name: "jeff"}
    data.save()
    data.update()
    data.insert()
}

以上就是go语言interface接口继承多态示例及定义解析的详细内容,更多关于go语言interface接口继承多态的资料请关注服务器之家其它相关文章!

原文链接:https://www.cnblogs.com/guyouyin123/p/13865340.html

延伸 · 阅读

精彩推荐
  • GolangGolang发送http GET请求的示例代码

    Golang发送http GET请求的示例代码

    这篇文章主要介绍了Golang发送http GET请求的示例代码,帮助大家更好的理解和使用golang,感兴趣的朋友可以了解下...

    陶士涵10952021-02-21
  • GolangGO语言ini配置文件的读取的操作

    GO语言ini配置文件的读取的操作

    这篇文章主要介绍了GO语言ini配置文件的读取的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    Coldestmonth6962021-06-23
  • Golang解析golang 标准库template的代码生成方法

    解析golang 标准库template的代码生成方法

    这个项目的自动生成代码都是基于 golang 的标准库 template 的,所以这篇文章也算是对使用 template 库的一次总结,本文通过实例代码给大家介绍的非常详细,...

    千里之行,始于足下10542021-11-30
  • Golang理解Golang中的数组(array)、切片(slice)和map

    理解Golang中的数组(array)、切片(slice)和map

    这篇文章主要介绍了理解Golang中的数组(array)、切片(slice)和map,本文先是给出代码,然后一一分解,并给出一张内图加深理解,需要的朋友可以参考下 ...

    junjie5352020-04-09
  • Golanggolang实现整型和字节数组之间的转换操作

    golang实现整型和字节数组之间的转换操作

    这篇文章主要介绍了golang实现整型和字节数组之间的转换操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    思维的深度12312021-03-05
  • GolangGo语言实现的排列组合问题实例(n个数中取m个)

    Go语言实现的排列组合问题实例(n个数中取m个)

    这篇文章主要介绍了Go语言实现的排列组合问题,结合实例形式分析了Go语言实现排列组合数学运算的原理与具体操作技巧,需要的朋友可以参考下 ...

    books19584622020-05-05
  • GolangGolang的func参数及返回值操作

    Golang的func参数及返回值操作

    这篇文章主要介绍了Golang的func参数及返回值操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    懒人程序猿6142021-06-15
  • GolangGo实现Redis连接池方法

    Go实现Redis连接池方法

    为了更深入了解golang连接池的实现,自已又重写了一遍连接池。文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    ReganYue9702021-09-15