Go语言封装、继承、接口、多态和断言的案例

[daodu]Go语言开发者认为:面向对象就是特定类型(结构体)有着自己的方法,利用这个方法完成面向对象编程,并没有提封装、继承、多态。所以Go语言进行面向对象编程时,重点在于灵活使用方法。Go语言有着自己对面向对象的理解,它也有着自己的封装、继承、多态。[/daodu]

[erji]封装[/erji]

<pre>

    //Learn_Go/main.go

    package main


    import (

    "fmt"

    )


    type People struct {

    name string

    age int

    }


    func (p *People) SetName(name string)  {

    p.name = name

    }


    func (p *People) SetAge(age int)  {

    p.age = age

    }


    func (p *People) GetName() string{

    return p.name

    }


    func (p *People) GetAge() int{

    return p.age

    }


    func main()  {

    peo := new(People)

    peo.SetName("derek")

    peo.SetAge(22)

    fmt.Println(peo.GetName(),peo.GetAge())    //derek 22

    }

</pre>

[erji]继承[/erji]

<pre>

    //Learn_Go/main.go

    package main


    import "fmt"


    type People struct {

    name string

    age int

    }


    type Teacher struct {

    People

    classroom string

    }


    func main()  {

    tea := Teacher{People{"derek",22},"911"}

    fmt.Println(tea.classroom,tea.name,tea.age)    //911 derek 22

    }

</pre>

[erji]接口[/erji]

接口是一组行为规范的定义;接口中只能有方法声明,方法只能有名次、参数、返回值,不能有方法体;每个接口中可以有多个方法,结构体把接口总所有方法都重写后,结构体就属于接口类型;Go语言中接口和结构体之间的关系是传统面向对象中is-like-a的关系。

<pre>

    //Learn_Go/main.go

    package main


    import "fmt"


    type Live interface {

    run(i int)

    eat(thing string)

    }


    type People struct {

    name string

    }


    func (p *People) run(i int)  {

    fmt.Println(p.name,"跑了",i,"米")

    }


    func (p *People) eat(thing string)  {

    fmt.Println(p.name,"正在吃",thing)

    }


    func main()  {

    peo := People{"derek"}

    peo.run(100)

    peo.eat("面包")

    }

</pre>

[erji]多态[/erji]

多态:同一件事情由于条件不同产生的结果不同;由于go语言中结构体不能相互转换,所以没有结构体的多态,只有基于接口的多态。

<pre>

    //Learn_Go/main.go

    package main


    import "fmt"


    type Live interface {

    run()

    }


    type People struct {

    name string

    }


    type Animal struct {

    name string

    }


    func (p *People) run()  {

    fmt.Printf("%v在跑步",p.name)

    }


    func (a *Animal) run()  {

    fmt.Printf("%v在跑步",a.name)

    }


    func allrun(live Live)  {

    live.run()

    }


    func main()  {

    //接口不能实例化,只能对接口的结构体实例化

    peo := &People{"derek"}

    allrun(peo)      //derek在跑步

    //多态,条件不同结果不同

    a := &Animal{"小狗"}

    allrun(a)      //小狗在跑步

    }

</pre>

[erji]断言[/erji]

只要实现了接口的全部方法认为这个类型属于接口类型,如果编写一个接口,这个接口没有任何方法,这是认为所有类型都是了这个接口,所以Go语言中interface{}代表任意类型;如果interface{]作为方法参数就可以接受任意类型,但是在程序中有时有需要知道这个参数到底是什么类型,这个时候就需要使用断言。

(1)断言可以有一个返回值,如果判断结果是指定类型返回变量值,否则报错

<pre>

    //Learn_Go/main.go

    package main


    import "fmt"


    func main()  {

    var i interface{} = 44    //i是int类型

    result1 := i.(int)

    fmt.Println(result1)    //44


    result2 := i.(string)

    fmt.Println(result2)    //panic: interface conversion: interface {} is int, not string

    }

</pre>

(2)可以查看值的类型

<pre>

    //Learn_Go/main.go

    package main


    import "fmt"


    func main()  {

    var i interface{} = 44    //i是int类型

    result,ok := i.(int)

    fmt.Println(result,ok)    //44 true

    fmt.Printf("%T",result)    //int

    }

</pre>

(3)通过断言判断值的类型

<pre>

    //Learn_Go/main.go

    package main


    import "fmt"


    func demo(i interface{})  {

    _,ok := i.(int)

    if ok{

    fmt.Println("参是int类型")

    return

    }

    _,ok = i.(string)

    if ok{

    fmt.Println("参是string类型")

    return

    }

    fmt.Println("参数类型不确定,不是int和string类型")

    }


    func main()  {

    demo(8)            //参是int类型

    demo("derek")      //参是string类型

    demo(3.146)        //参数类型不确定,不是int和string类型

    }

</pre>

https://www.linuxprobe.com/go-encapsulation-inheritance.html

推荐阅读更多精彩内容