接口interface

  1. 接口是一个或多个方法签名的集合

  2. 只要某个类型拥有该接口的所有方法签名,即算实现该接口,无需显示声明实现了哪个接口,这称为 Structural typing

  3. 接口只有方法声明,没有实现,没有数据字段

  4. 接口可以匿名嵌入其它接口,或切入到结构中去

  5. 将对象赋值给接口时,会发生拷贝,而接口内部存储的是指向这个复制品到指针,既无法修改复制品的状态,也无法获取指针

  6. 只有当接口存储的类型和对象都为 nil 时,接口才等于 nil

  7. 接口调用不会做 receiver 的自动转换

  8. 接口同样支持匿名字段方法

  9. 接口也可实现类似 OOP 中的多态

  10. 空接口可以作为任何类型数据的容器

那么,让我们先来看一个简单的接口应用案例:

package main

import "fmt"

/**
定义接口
*/
type USB interface {
Name() string // 定义了名为Name的方法且返回类型为String
Connect() // 定义了名为Connect的方法,没有返回类型形如java中的void
} /**
使用结构体(java中的class) 来实现接口中的方法
具体如何实现是通过为定义的结构体绑定方法来实现,故可以看到下面代码开始先定义一个结构体之后再为这个结构添加方法
*/
type PhoneConnecter struct {
// 定义内部变量
name string
} func (phone PhoneConnecter) Name() string {
return phone.name
} func (phone PhoneConnecter) Connect() {
fmt.Println("Connect:", phone.name)
} func main() {
/*var a USB
a = PhoneConnecter{"PhoneConnecter"}*/
//以上注释代码可以简写为以下形式
a := PhoneConnecter{"PhoneConnecter"}
a.Connect()
//那么有人问来,那你怎么知道 a 是实现来 USB 接口呢?那么我们再定义一个Disconnect函数,参数就传入 USB 类型
Disconnect(a)
/**
从结果可以看出实现接口并没有声明实现哪个接口
*/
} func Disconnect(usb USB) {
fmt.Println("Disconnected.")
}

运行结果:

1
2
Connect: PhoneConnecter
Disconnected.

类型断言

  1. 通过类型断言的 ok pattern可以判断接口中的数据类型

  2. 使用 type switch 则可以针对空接口进行比较全面的类型判断

接口转换

  可以将拥有超集的接口转换为子集的接口

更加深入的示例:

 1 package main
2
3 import (
4 "fmt"
5 )
6
7 /**
8 定义接口
9 */
10 type USB interface {
11 Name() string // 定义了名为Name的方法且返回类型为String
12 Connecter   // 接口嵌套,USB 接口也就拥有了 Connecter 接口中 Connect() 方法
13 }
14
15 type Connecter interface {
16 Connect()
17 }
18
19 /**
20 定义结构体
21 */
22 type PhoneConnecter struct {
23 // 定义内部变量
24 name string
25 }
26
27 /**
28 真对结构体绑定的方法method
29 */
30 func (phone PhoneConnecter) Name() string {
31 return phone.name
32 }
33
34 func (phone PhoneConnecter) Connect() {
35 fmt.Println("Connect:", phone.name)
36 }
37
38 func main() {
39 a := PhoneConnecter{"PhoneConnecter"}
40 a.Connect()
41 Disconnect(a)
42 DisconnectAll(a)
43 DisconnectSwitch(a)
44
45 // 演示接口类型转换
46 phone := PhoneConnecter{"PhoneConnecter"} // 声明 PhoneConnecter,其实它是实现来 USB 接口的
47 var b Connecter // 声明 Connecter 接口
48 b = Connecter(phone) // 将 USB接口的类型强制转换为 Connecter 类型。即Go语言中接口转换只能从高——>低
49 b.Connect()   // 当前只能调用 Connect 方法并没有 Name 方法了,因为它已经是 Connecter 类型了,不存在 Name 方法
50 }
51
52 func Disconnect(usb USB) {
53 /**
54 这里是通过类型断言来判定当前是哪个对象调用并打印
55 类型断言格式:usb.(要判断的对象),判断传入的是否为PhoneConnecter类型
56 */
57 if phone, ok := usb.(PhoneConnecter); ok {
58 fmt.Println("Disconnected:", phone.name)
59 return
60 }
61 fmt.Println("Unknown decive.")
62 }
63
64 /**
65 Go语言中类型定义只要符合定义的接口那么它就实现来该接口,在java语言中都有一个顶级父类叫 Object。那么在Go语言中有吗?
66 当然有的,通过接口概念可以了解到当我们定义一个空接口的时候,任何类型都会继承它。那么针对Disconnect方法我们就可以定义一种更加广泛的应用方式
67 */
68 func DisconnectAll(usb interface{}) {
69 if phone, ok := usb.(PhoneConnecter); ok {
70 fmt.Println("DisconnectAll:", phone.name)
71 return
72 }
73 fmt.Println("Unknown decive.")
74 }
75
76 /**
77 在Go语言中可以用另外一种方式进行断言,叫:type switch
78 */
79 func DisconnectSwitch(usb interface{}) {
80 switch v := usb.(type) {
81 case PhoneConnecter:
82 fmt.Println("DisconnectSwitch:", v.name)
83 default:
84 fmt.Println("Unknown decive.")
85 }
86 }

运行结果:

1
2
3
4
5
Connect: PhoneConnecter
Disconnected: PhoneConnecter
DisconnectAll: PhoneConnecter
DisconnectSwitch: PhoneConnecter
Connect: PhoneConnecter

GO语言基础之interface的更多相关文章

  1. GO_08:GO语言基础之interface

    接口interface 1. 接口是一个或多个方法签名的集合 2. 只要某个类型拥有该接口的所有方法签名,即算实现该接口,无需显示声明实现了哪个接口,这称为 Structural typing 3. ...

  2. C#语言基础

    第一部分 了解C# C#是微软公司在2000年7月发布的一种全新且简单.安全.面向对象的程序设计语言,是专门为.NET的应用而开发的.体现了当今最新的程序设计技术的功能和精华..NET框架为C#提供了 ...

  3. 【GoLang】GO语言系列--002.GO语言基础

    002.GO语言基础 1 参考资料 1.1 http://www.cnblogs.com/vimsk/archive/2012/11/03/2736179.html 1.2 https://githu ...

  4. OC语言基础知识

    OC语言基础知识 一.面向对象 OC语言是面向对象的,c语言是面向过程的,面向对象和面向过程只是解决问题的两种思考方式,面向过程关注的是解决问题涉及的步骤,面向对象关注的是设计能够实现解决问题所需功能 ...

  5. Java学习总结(二)----Java语言基础

    1.     Java语言基础 2.1 关键字 定义:被java语言赋予特殊含义的单词 特点:关键字中的字母都为小写 用于定义数据类型的关键字 class,interface,byte,short,i ...

  6. JavaScript基础---语言基础(1)

    写在前面: 通过四篇博客把JS基础中的基础整理一下,方便自己查阅,这些内容对于实际项目开发中也许并不会在意,但是作为JS的语言基础,自觉还是应该熟悉.在完成这三篇博客(JavaScript基础---语 ...

  7. Object Pascal 语言基础

    Delphi 是以Object Pascal 语言为基础的可视化开发工具,所以要学好Delphi,首先要掌握的就是Object Pascal 语言.Object Pascal语言是Pascal之父在1 ...

  8. C#语言基础——7月21日

    C#语言基础 一.语言基础 (一).函数的四要素:      名称,输入,输出,加工(二).主函数.输出语句.输入语句:     Static void Main(string[] args)//下划 ...

  9. 李洪强iOS开发之OC语言基础知识

    OC语言基础知识 一.面向对象 OC语言是面向对象的,c语言是面向过程的,面向对象和面向过程只是解决问题的两种思考方式,面向过程关注的是解决问题涉及的步骤,面向对象关注的是设计能够实现解决问题所需功能 ...

随机推荐

  1. C#中的特性 (Attribute) 入门 (一)

    C#中的特性 (Attribute) 入门 (一) 饮水思源 http://www.cnblogs.com/Wind-Eagle/archive/2008/12/10/1351746.html htt ...

  2. Python中 *args 和 **kwargs 的区别

    先来看个例子: def foo(*args, **kwargs): print 'args = ', args print 'kwargs = ', kwargs print '----------- ...

  3. 【WIN10】我的第一個WIN10-UWP應用——古文觀止

    已上架,下載地址:https://www.microsoft.com/store/apps/9nblggh6cc32 特點是:繁體豎排,隱藏/顯示標點符號. 截幾張圖來瞅瞅. 1.主界面 這張圖使用的 ...

  4. 【二分】【动态规划】Gym - 101156E - Longest Increasing Subsequences

    求最长上升子序列方案数. 转载自:http://blog.csdn.net/u013445530/article/details/47958617,如造成不便,请博主联系我. 数组A包含N个整数(可能 ...

  5. [CodeChef-QTREE6]Query on a tree VI

    题目大意: 给你一棵黑白树,每个点默认是白色,要求支持以下两种操作: 1.改变一个点的颜色: 2.除去连接不同颜色的点的边,求某个点连通块的大小. 思路: 对原树维护两个树链剖分, 一棵维护当点x为白 ...

  6. MyBatis -- generator 逆向工程

    一.引言 官网文档:http://www.mybatis.org/generator/index.html 通过使用官方提供的mapper自动生成工具,mybatis-generator-core-1 ...

  7. C++使用new和不使用new创建对象区别

    前言 在使用面向对象的时候,发现使用new和不使用new创建的对象区别还是蛮大的,做个总结: 总结 new创建的是一个指向类对象的指针,需要指针进行接收,一处初始化,多处使用,但是不用new创建的话不 ...

  8. word-ladder总结

    title: word ladder总结 categories: LeetCode tags: 算法 LeetCode comments: true date: 2016-10-16 09:42:30 ...

  9. NOIP 2008 传纸条 NOIP 2000 方块取数 多线程DP

    思路都是一样,建立一个四维dp然后跑一发就完了 当然,也可以像我这么帅的人,降成三维再傻傻的跑一发啦啦啦~ #include<iostream> #include<stdio.h&g ...

  10. Opencv各版本的配置

    OpenCV 2.49 + VS2012 配置指南 首先下载 OpenCV2.4.9 源码: 一.  配置系统环境变量 1.  将源码解压到指定目录: 2.  将 opencv 添加到系统环境变量: ...