为了账号安全,请及时绑定邮箱和手机立即绑定

Golang 中的接口 (interface)

标签:
Go

依赖于接口而不是实现,优先使用组合而不是继承,这是程序抽象的基本原则。Golang 中的 interface 让编码更灵活、易扩展,使得 Go 拥有了面向对象多态的特性。在此我们记住三点就够了:

  1. 方法声明的集合

  2. 任何类型的对象实现了在接口中声明的全部方法,则表明该类型实现了对应接口。

  3. 可以作为一种数据类型,实现了该接口的任何对象都可以给对应的接口类型变量赋值。

结合例子去理解上述三点:

package mainimport "fmt"import "math"// 几何图形的接口(interface)type geometry interface {
    area() float64    perim() float64
}// rect 和 circle 实现 geometry 接口type rect struct {
    width, height float64
}
type circle struct {
    radius float64
}// 实现了接口中声明的所有方法即实现了该接口,这里 rects 实现了 geometry 接口func (r rect) area() float64 {    return r.width * r.height
}
func (r rect) perim() float64 {    return 2*r.width + 2*r.height
}// circles 实现 geometry 接口func (c circle) area() float64 {    return math.Pi * c.radius * c.radius
}
func (c circle) perim() float64 {    return 2 * math.Pi * c.radius
}// 定义的接口可以作为一种数据类型,当一个变量的类型为一个接口类型时,这个变量可以调用接口中定义的方法。// 这里定义一个函数,接收一个类型为 geometry 的参数变量func measure(g geometry) {
    fmt.Println(g)
    fmt.Println(g.area())
    fmt.Println(g.perim())
}func main() {
    r := rect{width: 3, height: 4}
    c := circle{radius: 5}    // The circle and rect struct types both implement the geometry interface so we can use instances of these structs as arguments to measure.
    // rect 和 circle 结构类型都实现了 geometry 接口,所以我们能够把它们的对象作为参数传给 measure 函数
    // 在 measure 函数内部,参数对象调用了所属类型实现的接口方法。
    measure(r)
    measure(c)
}

一种类型只要实现接口声明的方法就算实现了接口,同样一种类型能同时支持实现多个接口了,一个接口也能被多种类型实现。如果一种类型实现了某个接口,那么这种类型的对象能够赋值给这个接口类型的变量。

package mainimport "fmt"type I interface {
  method1()
}

type T struct{}

func (T) method1()  {}func main()  {
  var i I = T{}
  fmt.Println(i)
}

最后的一部分解释一下 interface{} 类型,这种类型的接口没有声明任何一个方法,俗称空接口。因为任何类型的对象都默认实现了空接口(上文提到任意类型只要实现了接口的方法就算实现了对应的接口,由于空接口没有方法,故所有类型默认都实现了空接口)在需要任意类型变量的场景下非常有用。

package mainimport (    "fmt")func PrintAll(vals []interface{}) {    for _, val := range vals {
        fmt.Println(val)
    }
}func main() {
    names := []string{"stanley", "david", "oscar"}
    vals := make([]interface{}, len(names))    for i, v := range names {
        vals[i] = v
    }
    PrintAll(vals)
}// stanley// david// oscar

推荐阅读



作者:黄文威
链接:https://www.jianshu.com/p/d80f38598d94

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消