概述package mainimport "fmt"type Shaper interface { Area() float32}type Square struct { side float32}func (sq *Square) Area() float32 { return sq.side * sq.side}func main() { sq1 := new(S @H_502_7@package mainimport "fmt"type Shaper interface { Area() float32}type Square struct { sIDe float32}func (sq *Square) Area() float32 { return sq.sIDe * sq.sIDe}func main() { sq1 := new(Square) sq1.sIDe = 5 var areaIntf Shaper areaIntf = sq1 // shorter,without separate declaration: // areaIntf := Shaper(sq1) // or even: // areaIntf := sq1 fmt.Printf("The square has area: %f\n",areaIntf.Area())}
上面的程序定义了一个结构体 Square
和一个接口 Shaper
,接口有一个方法 Area()
。
在 main()
方法中创建了一个 Square
的实例。在主程序外边定义了一个接收者类型是 Square
方法的 Area()
,用来计算正方形的面积:结构体 Square
实现了接口 Shaper
。
所以可以将一个 Square
类型的变量赋值给一个接口类型的变量:areaIntf = sq1
。
现在接口变量包含一个指向 Square
变量的引用,通过它可以调用 Square
上的方法 Area()
。当然也可以直接在 Square
的实例上调用此方法,但是在接口实例上调用此方法更令人兴奋,它使此方法更具有一般性。接口变量里包含了接收者实例的值和指向对应方法表的指针。
这是 多态 的 Go 版本,多态是面向对象编程中一个广为人知的概念:根据当前的类型选择正确的方法,或者说:同一种类型在不同的实例上似乎表现出不同的行为。
如果 Square
没有实现 Area()
方法,编译器将会给出清晰的错误信息:
@H_502_7@cannot use sq1 (type *Square) as type Shaper in assignment:*Square does not implement Shaper (missing Area method)
如果 Shaper
有另外一个方法 Perimeter()
,但是Square
没有实现它,即使没有人在 Square
实例上调用这个方法,编译器也会给出上面同样的错误。
扩展一下上面的例子,类型 Rectangle
也实现了 Shaper
接口。接着创建一个 Shaper
类型的数组,迭代它的每一个元素并在上面调用 Area()
方法,以此来展示多态行为:
@H_502_7@package mainimport "fmt"type Shaper interface { Area() float32}type Square struct { sIDe float32}func (sq *Square) Area() float32 { return sq.sIDe * sq.sIDe}type Rectangle struct { length,wIDth float32}func (r Rectangle) Area() float32 { return r.length * r.wIDth}func main() { r := Rectangle{5,3} // Area() of Rectangle needs a value q := &Square{5} // Area() of Square needs a pointer // shapes := []Shaper{Shaper(r),Shaper(q)} // or shorter shapes := []Shaper{r,q} fmt.Println("LooPing through shapes for area ...") for n,_ := range shapes { fmt.Println("Shape details: ",shapes[n]) fmt.Println("Area of this shape is: ",shapes[n].Area()) }}
在调用 shapes[n].Area()
这个时,只知道 shapes[n]
是一个 Shaper
对象,最后它摇身一变成为了一个 Square
或 Rectangle
对象,并且表现出了相对应的行为。
在调用 shapes[n].Area()
这个时,只知道 shapes[n]
是一个 Shaper
对象,最后它摇身一变成为了一个 Square
或 Rectangle
对象,并且表现出了相对应的行为。
@H_502_7@package mainimport "fmt"type stockposition struct { ticker string sharePrice float32 count float32}/* method to determine the value of a stock position */func (s stockposition) getValue() float32 { return s.sharePrice * s.count}type car struct { make string model string price float32}/* method to determine the value of a car */func (c car) getValue() float32 { return c.price}/* contract that defines different things that have value */type valuable interface { getValue() float32}func showValue(asset valuable) { fmt.Printf("Value of the asset is %f\n",asset.getValue())}func main() { var o valuable = stockposition{"GOOG",577.20,4} showValue(o) o = car{"BMW","M3",66500} showValue(o)}
数据类型实现了接口,就能使用以接口变量为参数的方法
备注:
有的时候,也会以一种稍微不同的方式来使用接口这个词:从某个类型的角度来看,它的接口指的是:它的所有导出方法,只不过没有显式地为这些导出方法额外定一个接口而已。
总结
以上是内存溢出为你收集整理的golang interface接口全部内容,希望文章能够帮你解决golang interface接口所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
评论列表(0条)