加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

golang interface接口

发布时间:2020-12-16 09:33:24 所属栏目:大数据 来源:网络整理
导读: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 = 5var areaIntf ShaperareaIntf = sq1// shorte
package main

import "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: %fn",areaIntf.Area())
}

  

上面的程序定义了一个结构体?Square?和一个接口?Shaper,接口有一个方法?Area()

在?main()?方法中创建了一个?Square?的实例。在主程序外边定义了一个接收者类型是?Square?方法的?Area(),用来计算正方形的面积:结构体?Square?实现了接口?Shaper?。

所以可以将一个?Square?类型的变量赋值给一个接口类型的变量:areaIntf = sq1?。

现在接口变量包含一个指向?Square?变量的引用,通过它可以调用?Square?上的方法?Area()。当然也可以直接在?Square?的实例上调用此方法,但是在接口实例上调用此方法更令人兴奋,它使此方法更具有一般性。接口变量里包含了接收者实例的值和指向对应方法表的指针。

这是?多态?的 Go 版本,多态是面向对象编程中一个广为人知的概念:根据当前的类型选择正确的方法,或者说:同一种类型在不同的实例上似乎表现出不同的行为。

如果?Square?没有实现?Area()?方法,编译器将会给出清晰的错误信息:

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()?方法,以此来展示多态行为:

package main

import "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?对象,并且表现出了相对应的行为。

package main

import "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 %fn",asset.getValue())
}

func main() {
	var o valuable = stockPosition{"GOOG",577.20,4}
	showValue(o)
	o = car{"BMW","M3",66500}
	showValue(o)
}

  数据类型实现了接口,就能使用以接口变量为参数的方法

备注:

有的时候,也会以一种稍微不同的方式来使用接口这个词:从某个类型的角度来看,它的接口指的是:它的所有导出方法,只不过没有显式地为这些导出方法额外定一个接口而已。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读