栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Go语言

第001节:接口的使用

Go语言 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

第001节:接口的使用

1.1 什么是接口?

面向对象世界中的接口的一般定义是“接口定义对象的行为”。它表示让指定对象应该做什么。实现这种行为的方法(实现细节)是针对对象的。

在Go中,接口是一组方法签名。当类型为接口中的所有方法提供定义时,它被称为实现接口。它与OOP非常相似。接口指定了类型应该具有的方法,类型决定了如何实现这些方法。

它把所有的具有共性的方法定义在一起,任何其他类型只要实现了这些方法就是实现了这个接口

接口定义了一组方法,如果某个对象实现了某个接口的所有方法,则此对象就实现了该接口。

1.2 接口的定义语法

定义接口

type interface_name interface {   method_name1 [return_type]   method_name2 [return_type]   method_name3 [return_type]   ...   method_namen [return_type]}type struct_name struct {   }func (struct_name_variable struct_name) method_name1() [return_type] {   }...func (struct_name_variable struct_name) method_namen() [return_type] {   }

示例代码:

package mainimport (    "fmt")type Phone interface {    call()}type NokiaPhone struct {}func (nokiaPhone NokiaPhone) call() {    fmt.Println("I am Nokia, I can call you!")}type IPhone struct {}func (iPhone IPhone) call() {    fmt.Println("I am iPhone, I can call you!")}func main() {    var phone Phone    phone = new(NokiaPhone)    phone.call()    phone = new(IPhone)    phone.call()}

运行结果:

I am Nokia, I can call you!I am iPhone, I can call you!

interface可以被任意的对象实现一个对象可以实现任意多个interface任意的类型都实现了空interface(我们这样定义:interface{}),也就是包含0个method的interface

1.3 interface值

package mainimport "fmt"type Human struct {    name  string    age   int    phone string}type Student struct {    Human  //匿名字段    school string    loan   float32}type Employee struct {    Human   //匿名字段    company string    money   float32} //Human实现Sayhi方法func (h Human) SayHi() {    fmt.Printf("Hi, I am %s you can call me on %sn", h.name, h.phone)} //Human实现Sing方法func (h Human) Sing(lyrics string) {    fmt.Println("La la la la...", lyrics)} //Employee重写Human的SayHi方法func (e Employee) SayHi() {    fmt.Printf("Hi, I am %s, I work at %s. Call me on %sn", e.name,        e.company, e.phone) //Yes you can split into 2 lines here.}// Interface Men被Human,Student和Employee实现// 因为这三个类型都实现了这两个方法type Men interface {    SayHi()    Sing(lyrics string)}func main() {    mike := Student{Human{"Mike", 25, "222-222-XXX"}, "MIT", 0.00}    paul := Student{Human{"Paul", 26, "111-222-XXX"}, "Harvard", 100}    sam := Employee{Human{"Sam", 36, "444-222-XXX"}, "Golang Inc.", 1000}    Tom := Employee{Human{"Sam", 36, "444-222-XXX"}, "Things Ltd.", 5000}    //定义Men类型的变量i    var i Men    //i能存储Student    i = mike    fmt.Println("This is Mike, a Student:")    i.SayHi()    i.Sing("November rain")    //i也能存储Employee    i = Tom    fmt.Println("This is Tom, an Employee:")    i.SayHi()    i.Sing("Born to be wild")    //定义了slice Men    fmt.Println("Let's use a slice of Men and see what happens")    x := make([]Men, 3)    //T这三个都是不同类型的元素,但是他们实现了interface同一个接口    x[0], x[1], x[2] = paul, sam, mike    for _, value := range x {        value.SayHi()    }}

运行结果:

    This is Mike, a Student:    Hi, I am Mike you can call me on 222-222-XXX    La la la la... November rain    This is Tom, an Employee:    Hi, I am Sam, I work at Things Ltd.. Call me on 444-222-XXX    La la la la... Born to be wild    Let's use a slice of Men and see what happens    Hi, I am Paul you can call me on 111-222-XXX    Hi, I am Sam, I work at Golang Inc.. Call me on 444-222-XXX    Hi, I am Mike you can call me on 222-222-XXX

那么interface里面到底能存什么值呢?如果我们定义了一个interface的变量,那么这个变量里面可以存实现这个interface的任意类型的对象。例如上面例子中,我们定义了一个Men interface类型的变量m,那么m里面可以存Human、Student或者Employee值

当然,使用指针的方式,也是可以的

但是,接口对象不能调用实现对象的属性

interface函数参数

interface的变量可以持有任意实现该interface类型的对象,这给我们编写函数(包括method)提供了一些额外的思考,我们是不是可以通过定义interface参数,让函数接受各种类型的参数

嵌入interface

package mainimport "fmt"type Human interface {    Len()}type Student interface {    Human}type Test struct {}func (h *Test) Len() {    fmt.Println("成功")}func main() {    var s Student    s = new(Test)    s.Len()}

示例代码:

package testimport (    "fmt")type Controller struct {    M int32}type Something interface {    Get()    Post()}func (c *Controller) Get() {    fmt.Print("GET")}func (c *Controller) Post() {    fmt.Print("POST")}
package mainimport (    "fmt"    "test")type T struct {    test.Controller}func (t *T) Get() {    //new(test.Controller).Get()    fmt.Print("T")}func (t *T) Post() {    fmt.Print("T")}func main() {    var something test.Something    something = new(T)    var t T    t.M = 1    //  t.Controller.M = 1    something.Get()}

Controller实现了所有的Something接口方法,当结构体T中调用Controller结构体的时候,T就相当于Java中的继承,T继承了Controller,因此,T可以不用重写所有的Something接口中的方法,因为父构造器已经实现了接口。

如果Controller没有实现Something接口方法,则T要调用Something中方法,就要实现其所有方法。

如果something = new(test.Controller)则调用的是Controller中的Get方法。

T可以使用Controller结构体中定义的变量

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/793616.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号