Go语言提供了另外一种数据类型,即接口,它把所有具有共性的方法定义在一起,
任何其它类型只要实现了这些方法就是实现了这个接口。

接口代表一种调用契约,是多个方法声明的集合。
在某些动态语言里,接口(interface)也被称作协议(protocol)。
准备交互的双方,共同遵守事先约定的规则,使得无须知道对方身份的情况下进行协作。
接口要实现的是做什么,而不关心怎么做,谁来做。

接口解除了类型依赖,有助于减少用户可视方法,屏蔽内部结构和实现细节。
似乎好处很多,但这并不意味着可以滥用接口,毕竟接口实现机制会有运行开销。
对于相同包,或者不会频繁变化的内部模块结构,并不需要抽象出接口来强行分离。
接口最常见的使用场景是对包外提供访问,或预留扩展空间。

Go的接口类型用于定义一组行为,其中每个行为都由一个方法声明表示。
接口类型中的方法声明只有方法签名而没有方法体,而方法签名包括且仅包括方法的名称、参数列表和结果列表。

举个例子,如果要定义“聊天”相关的一组行为,可以这样写:

type Talk interface {
Hello(userName string) string
Talk(heard string) (saying string,end bool,err error)
}

type、接口类型名称、interface以及由花括号包裹的方法声明集合,共同组成了一个接口类型声明。
注意,其中每个方法声明必须独占一行。

只要一个数据类型的方法集合中包含Talk接口声明的所有方法,那么它就一定是Talk接口的实现类型。

//定义接口
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_var struct_name) method_name1() [return_type] {
/*方法实现*/
} func (struct_name_var struct_name) method_name2() [return_type] {
/*方法实现*/
}

  

简单实例:

package main

import (
"fmt"
) //定义一个Phone接口
type Phone interface {
call() //接口中有一个call方法
} //定义诺基亚结构体
type NokiaPhone struct {
}
//实现call方法
func (nokkiaPhone NokiaPhone) call() {
fmt.Println("I am Nokia")
} //定义苹果结构体
type Iphone struct {
}
//实现call方法
func (iphone Iphone) call() {
fmt.Println("I am iphone")
} func main() {
//根据接口声明变量
var phone Phone //同一个接口变量就能实现多个结构体中的方法
phone = new(NokiaPhone) //创建一个指定类型的值,并返回该值的指针
phone.call() phone = new(Iphone)
phone.call()
} /*
I am Nokia
I am iphone
*/

编译器会根据方法集来判断是否实现了接口。
如果接口没有任何方法声明,那么就是一个空接口(interface{}),
它的用途类似面向对象里面的根类型Object,可被赋值为任何类型的对象。
接口变量默认值是nil,如果实现接口的类型支持,可做相等运算。

package main

import "fmt"

type tester interface {
test() string
string() string
} type data struct{} //定义结构体 func (*data) test() string {
return "5678"
} //实现test方法 func (data) string() string { //实现string
return "aaaaaaaaa"
} func main() {
var d data var t tester = &d //
fmt.Println(t.test()) //不论是data和*data都是指代同一个程序实体
fmt.Println(t.string())
}

可以像匿名字段那样,嵌入其它接口。
目标类型方法集中必须拥有包含嵌入接口方法在内的全部方法才算实现了该方法。

嵌入其它接口类型,相当于将其声明的方法集导入。
这就要求不能有同名方法,因为不支持重载。还有,不能嵌入自身或循环嵌入,那会导致递归错误。

package main

import "fmt"

type stringer interface {
string() string
} type tester interface {
test() string
stringer
} type data struct{} //定义结构体 func (*data) test() string {
return "5678"
} //实现test方法 func (data) string() string {
return "aaaaaaaaa"
} func main() {
var d data var t tester = &d //
fmt.Println(t.test())
fmt.Println(t.string())
} package main import "fmt" type stringer interface {
string() string
} type tester interface {
test() string
stringer
} type data struct{} func (*data) test() string {
return "5678"
} func (data) string() string {
return "aaaaaaaaa"
} func pp(a string) {
fmt.Println(a.string())
} func main() {
var d data var t tester = &d
pp(t) var s stringer = t
fmt.Println(s.string())
}

支持匿名接口类型,可直接用于变量定义,或作为结构字段类型。

package main

import "fmt"

type data struct{} //结构体data

func (data) string() string {
return "123456"
} type node struct {
data interface { //字段类型为接口
string() string
}
} func main() {
var t interface { //变量t为接口类型
string() string
} = data{} //空结构体 n := node{
data: t,
} fmt.Println(n.data.string()) //123456
}

类型推断可将接口变量还原为原始类型,或用来判断是否实现了某个更具体地接口类型。

package main

import "fmt"

type data int

func (d data) String() string {  //方法
return fmt.Sprintf("data:%d", d)
} func main() {
var d data = 15
var x interface{} = d if n, ok := x.(fmt.Stringer); ok {
fmt.Println(n)
} if d2, ok := x.(data); ok {
fmt.Println(d2)
} e := x.(error)
fmt.Println(e)
} /*
data:15
data:15
panic: interface conversion: main.data is not error: missing method Error
*/

  

go——接口的更多相关文章

  1. App开发:模拟服务器数据接口 - MockApi

    为了方便app开发过程中,不受服务器接口的限制,便于客户端功能的快速测试,可以在客户端实现一个模拟服务器数据接口的MockApi模块.本篇文章就尝试为使用gradle的android项目设计实现Moc ...

  2. 干货来袭-整套完整安全的API接口解决方案

    在各种手机APP泛滥的现在,背后都有同样泛滥的API接口在支撑,其中鱼龙混杂,直接裸奔的WEB API大量存在,安全性令人堪优 在以前WEB API概念没有很普及的时候,都采用自已定义的接口和结构,对 ...

  3. 12306官方火车票Api接口

    2017,现在已进入春运期间,真的是一票难求,深有体会.各种购票抢票软件应运而生,也有购买加速包提高抢票几率,可以理解为变相的黄牛.对于技术人员,虽然写一个抢票软件还是比较难的,但是还是简单看看123 ...

  4. Java基础Map接口+Collections工具类

    1.Map中我们主要讲两个接口 HashMap  与   LinkedHashMap (1)其中LinkedHashMap是有序的  怎么存怎么取出来 我们讲一下Map的增删改查功能: /* * Ma ...

  5. Java基础Map接口+Collections

    1.Map中我们主要讲两个接口 HashMap  与   LinkedHashMap (1)其中LinkedHashMap是有序的  怎么存怎么取出来 我们讲一下Map的增删改查功能: /* * Ma ...

  6. java基础_集合List与Set接口

    List接口继承了Collection的方法  当然也有自己特有的方法向指定位置添加元素   add(索引,添加的元素); 移除指定索引的元素   remove(索引) 修改指定索引的元素   set ...

  7. 【WCF】自定义错误处理(IErrorHandler接口的用法)

    当被调用的服务操作发生异常时,可以直接把异常的原始内容传回给客户端.在WCF中,服务器传回客户端的异常,通常会使用 FaultException,该异常由这么几个东东组成: 1.Action:在服务调 ...

  8. PHP以接口方式实现多重继承(完全模拟)--学习笔记

     1.UML类图: 2.PHP代码: <?php /** * Created by PhpStorm. * User: andy * Date: 16-11-23 * Time: 下午7:57 ...

  9. 【微框架】Maven +SpringBoot 集成 阿里大鱼 短信接口详解与Demo

    Maven+springboot+阿里大于短信验证服务 纠结点:Maven库没有sdk,需要解决 Maven打包找不到相关类,需要解决 ps:最近好久没有写点东西了,项目太紧,今天来一篇 一.本文简介 ...

  10. 【接口开发】浅谈 SOAP Webserver 与 Restful Webserver 区别

    接口,强大,简单,交互,跨越平台 下面简单阐述这两大接口思想 一 REST: REST是一种架构风格,其核心是面向资源,REST专门针对网络应用设计和开发方式,以降低开发的复杂性,提高系统的可伸缩性. ...

随机推荐

  1. 大数据(9) - Flume的安装与使用

    Flume简介 --(实时抽取数据的工具) 1) Flume提供一个分布式的,可靠的,对大数据量的日志进行高效收集.聚集.移动的服务,Flume只能在Unix环境下运行. 2) Flume基于流式架构 ...

  2. redisson笔记

    简介 Redisson - 是一个高级的分布式协调Redis客服端,能帮助用户在分布式环境中轻松实现一些Java的对象 (Bloom filter, BitSet, Set, SetMultimap, ...

  3. Visual Studio中“后期生成事件命令行” 中使用XCopy命令

    将程序所依赖的动态库与其他依赖文件做了分类,使用XCopy命令自动生成相应的目录结构. set source="$(TargetDir)" set output="$(S ...

  4. .net 编译原理

    这听起来像是个非常高大上的名字,上学的时候我们学过的编译原理或者编译技术实际上是在讲如何将高级程序语言如C++编译为计算机可以理解的汇编语言,这里说的编译原理只是想说明在.NET的世界里编译这件事儿和 ...

  5. win下如何查看那个网络端口被那个应用程序使用

    在运行里面键入cmd打开命令行窗口.     在命令行窗口键入命令: netstat -ano 第一和第二列是自己网络的端口和外网连接的端口,pid:(全称Process Identification ...

  6. 第二百一十九节,jQuery EasyUI,DateTimeBox(日期时间输入框)组件

    jQuery EasyUI,DateTimeBox(日期时间输入框)组件 学习要点: 1.加载方式 2.属性列表 3.方法列表 本节课重点了解 EasyUI 中 DateTimeBox(日期时间输入框 ...

  7. jquery添加!important样式

    $("span.colorFlag").parents("th").css("cssText","background-color ...

  8. linux 环境 tomcat 莫名奇妙挂掉

    ::-exec-] org.apache.coyote.http11.Http11Processor.service Error processing request java.lang.NullPo ...

  9. windows安装oracle11g

    windows上安装oracle11g   1.下载Oracle 11g R2 for Windows的版本 下载地址:https://www.oracle.com/technetwork/datab ...

  10. C++ 调用webservice 出现 函数返回值为 3 (SOAP_TAG_MISMATCH) 的解决方案

    最近在用C++ gsoap做webservice服务时,函数返回值为SOAP_TAG_MISMATCH (==3)错误码,原因是我传入wsdl地址时连同后面的?wsdl都传入了,如下: http:// ...