文档章节

Go接口——基本概念

秋风醉了
 秋风醉了
发布于 2016/07/11 15:18
字数 809
阅读 40
收藏 0

Go接口——基本概念

Interfaces are named collections of method signatures.

当你有看到一个接口类型时,你不知道它是什么,唯一知道的就是可以通过它的方法来做什么。

C++,Java 使用“侵入式”接口,主要表现在实现类需要明确声明自己实现了某个接口。这种强制性的接口继承方式是面向对象编程思想发展过程中一个遭受相当多质疑的特性。

**Go语言采用的是“非侵入式接口”,Go语言的接口有其独到之处:只要类型 T 的公开方法完全满足接口 I 的要求,就可以把类型 T 的对象用在需要接口 I 的地方,所谓类型 T 的公开方法完全满足接口 I 的要求,也即是类型 T 实现了接口 I 所规定的一组成员。**这种做法的学名叫做Structural Typing,有人也把它看作是一种静态的Duck Typing。

下面我们通过一组例子来演示如何定义一个接口,如何实现接口。

package main

import (
	"fmt"
	"math"
)

// 首字母小写,该函数不是导出的,就是说在包外不能调用
// 函数参数为 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}

	fmt.Printf("%T\n", r) //main.Rect
	fmt.Printf("%T\n", c) //main.Circle

	// r,c 所对应的类型实现了接口的所有方法,所以也是接口类型的变量
	measure(r) //可以调用
	measure(c)
}

// 使用type ... interface 定义接口
// 一般地,Go中接口的命名约定:接口名以er结尾。注意,这里并非强行要求,你完全可以不以 er 结尾。标准库中有些接口也不是以 er 结尾的。
type Geometry interface {
	Area() float64
	Perim() float64
}

type Rect struct {
	Width, Height float64 // 结构体 Rect 的成员变量,开头首字母大写,都是导出的
}

type Circle struct {
	Radius float64
}

// To implement an interface in Go, we just need to implement all the methods in the interface. Here we implement Geometry on Rect.
// 在go中,实现一个接口,只需要实现接口中定义的所有方法,而不需要指明所实现的接口。

func (r Rect) Area() float64 {
	return r.Width * r.Height
}
func (r Rect) Perim() float64 {
	return 2*r.Width + 2*r.Height
}

// end===== Geometry接口的 Rect 实现

func (c Circle) Area() float64 {
	return math.Pi * c.Radius * c.Radius
}
func (c Circle) Perim() float64 {
	return 2 * math.Pi * c.Radius
}

// end===== Geometry接口的 Circle 实现

这就是接口的基本概念和使用方法。我们再来看一下例子。

package main

import (
	"fmt"
)

// 定义 Phone 接口
// 只有一个方法声明
type Phone interface {
	sales() int
}

type NokiaPhone struct {
	price int
}

// 实现接口的方法,也就表示 NokiaPhone 是 Phone 接口的一个实现
func (nokiaPhone NokiaPhone) sales() int {
	return nokiaPhone.price
}

type IPhone struct {
	price int
}

// 实现接口的方法,也就表示 IPhone 是 Phone 接口的一个实现
func (iPhone IPhone) sales() int {
	return iPhone.price
}

type Person struct {
	phones []Phone //接口作为结构体数据成员
	name   string
	age    int
}

func (person Person) total_cost() int {
	var sum = 0
	for _, phone := range person.phones {
		sum += phone.sales()
	}
	return sum
}

func main() {
	var bought_phones = [5]Phone{
		NokiaPhone{price: 350},
		IPhone{price: 5000},
		IPhone{price: 3400},
		NokiaPhone{price: 450},
		IPhone{price: 5000},
	}

	var person = Person{name: "Jemy", age: 25, phones: bought_phones[:]}

	fmt.Println(person.name)
	fmt.Println(person.age)
	fmt.Println(person.total_cost())
}

参考:

https://gobyexample.com/interfaces

http://golanghome.com/post/11

========END========

© 著作权归作者所有

共有 人打赏支持
秋风醉了
粉丝 239
博文 572
码字总数 416654
作品 0
朝阳
程序员
私信 提问
第一章节:Revit API基本概念

本章我们只要记录下载我本人学习Revit二次开发过程的API基本概念 1.外部命令:IExternalCommand 2.外部应用:IExternalApplication 3.插件的属性(Transaction、Journaling) 4.Revit的应用类...

sinat_38321889
2017/11/21
0
0
Tensorflow基础

刚开始接触tensorflow,分享一些实用基础的Tensorflow基础教程链接: Tensorflow一些常用基本概念与函数(一) Tensorflow一些常用基本概念与函数(二) Tensorflow一些常用基本概念与函数(...

zhaokx3
2017/04/05
0
0
无痛的机器学习第二季目录

以下是对这一年来完成的文章的汇总贴,陆续还会有新的内容加入,尽情期待! 无痛的机器学习第一季目录传送门:无痛的机器学习第一季目录 增强学习 增强学习入门1——基本概念 增强学习入门2...

冯超
2017/11/22
0
0
新书预告 :《Struts2技术内幕》 —— Struts2源码研究和Web开发研究

http://www.iteye.com/topic/1117044 简单做一个新书预告,我写的《Struts2技术内幕》将在下个月问世。 这本书应该是国内比较少见的以研究Struts2的源码为主要目标的技术书籍。源码研究类的书...

ddatsh
2011/10/26
1K
8
【数据平台】python语言NLP库Gensim初识

1、基本介绍 Gensim是一款开源的第三方Python工具包,用于从原始的非结构化的文本中,无监督地学习到文本隐层的主题向量表达。它支持包括TF-IDF,LSA,LDA,和word2vec在内的多种主题模型算法...

fjssharpsword
2017/11/01
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Git工作原理

git跟传统的代码管理器(如svn)不同, 主要区别在于git多了个本地仓库以及缓存区,所以即使无法联网也一样能提交代码。 术语解释: 工作区间: 即我们创建的工程文件, 在编辑器可直观显示;...

Lienson
13分钟前
1
0
MySQL驱动对应Server版本、JDK版本

昨日生产上线,临时升级MySQL版本,导致连接不上。 应用JDK版本1.5 测试环境MySQL版本5.7 驱动版本5.1.40.jar 正常 生产环境MySQL版本8.0 驱动版本5.1.40.jar 连接不上 生产环境MySQL版本8.0...

zcjlq
15分钟前
7
0
千万级规模【高性能、高并发】互联网架构经验分羹

架构以及我理解中架构的本质 在开始谈我对架构本质的理解之前,先谈谈对今天技术沙龙主题的个人见解,千万级规模的网站感觉数量级是非常大的,对这个数量级我们战略上 要重 视 它 , 战术上又...

java知识分子
16分钟前
0
0
重磅!阿里巴巴工程师获得 containerd 社区席位,与社区共建云时代容器标准

重磅!阿里巴巴工程师获得 containerd 社区席位,与社区共建云时代容器标准 11 月 29 日,CNCF containerd 社区正式宣布:两位阿里巴巴工程师正式获得 containerd 社区席位,成为 containerd...

阿里云官方博客
17分钟前
0
0
你会用哪些JavaScript循环遍历

总结JavaScript中的循环遍历 定义一个数组和对象 const arr = ['a', 'b', 'c', 'd', 'e', 'f'];const obj = { a: 1, b: 2, c: 3, d: 4} for() 经常用来遍历数组元素 遍历值为数组...

peakedness丶
18分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部