接口

1 接口类型作为函数的传入参数时,里面只能调用接口的方法,接口绑定的对象的方法是无法调用的,

package main
import "fmt"

type cat struct {
    name string
}
type Ilife interface {
    cry()
}

func implement_Ilife(life2 Ilife)  {
    life2.cry()
    // 接口对象只能调用接口中的方法,接口绑定的对象的方法是无法调用的,
    //life2.run()
}
func (c *cat) cry() {
    println("喵喵喵")
}

func (c *cat) run() {
    println(c.name + " is running")
}

func main()  {
    c := cat{name: "Tom"}
    fmt.Println(c)
    // 由于cry接受的参数是指针变量,所以这里必须是&c才行,
    // 注意是地址可以赋值给普通变量,普通变量无法赋值给地址变量,
    implement_Ilife(&c)
}
View Code

2 当结构体A内的属性B实现了接口I时,结构体A同时也实现了接口I,

package main
import "fmt"

type voice struct {
}
type cat struct {
    voice
    name string
}
type IRun interface {
    run()
}
type ICry interface {
    cry()
}
func (c *cat) run(){
    println(c.name + " is running")
}
func (v *voice) cry(){
    println("喵喵喵")
}
// 当结构体A内的属性B实现了接口I时,结构体A同时也实现了接口I,
func main()  {
    c := cat{voice:voice{}, name:"Tom"}
    var i IRun
    i = &c // 这里必须要取地址,
    i.run()
    // 注意返回的m是绑定了i底层对象的实现了ICry的接口的一个副本,
    if m, yes := i.(ICry); yes{
        println("i下的voice实现了ICry接口,所以i也实现了该接口,")
        fmt.Println(m)
    } else {
        println("没有实现ICry接口")
    }
}
View Code

3 如果结构体A实现了接口P和接口Q,在程序中接口P绑定了A,但A仍然实现了接口Q,即利用类型断言的时候,可直接让接口Q绑定A,

package main

import "fmt"

type Intfe1 interface {
    GetName() string
}
type Intfe2 interface {
    GetAge() int
}
type father struct {
    name string
}
type son struct {
    father
    name string
}
func (f *father) GetName() string {
    fmt.Println(f.name)
    return f.name
}
func (s *son) GetName() string {
    fmt.Println(s.name)
    return s.name
}
func (s *son) GetAge() int {
    return 5
}
func main()  {
    var i2 Intfe2
    s := son{father: father{name:"jack"},
               name: "tom"}
    i2 = &s
    if s_copy,ok := i2.(Intfe1); ok{
        fmt.Println(s_copy)
        println("实现了接口Intfe1")
    }
}
View Code

4 结构体A实现了接口I中的方法M,并且结构体里的很多属性也实现了这方法时,调用该方法就是调用的A实现的方法,这里相当于重写了该方法,这里和结构体的属性特点是一样的,都是就近原则,当结构体的父类和爷类里都有某个属性时,默认调用父类的,

package main
import "fmt"

type Intfa interface {
    GetName()
}

type father struct {
    name string
}

type son struct {
    father
    name string
}

func (s son) GetName() {
    fmt.Println("GetName方法重写了,调用最后重写的方法")
    fmt.Println(s.name)
}
func (f father) GetName() {
    fmt.Println(f.name)
}
func main()  {
    var i Intfa
    s := son{father:father{name: "tom"},
             name: "jack"}
    i = s
    i.GetName()
}
View Code

参考:https://learnku.com/docs/qianxi-golang/section-4-method-rewriting/6428

posted on 2020-11-23 13:58  吃我一枪  阅读(147)  评论(0编辑  收藏  举报

导航