go基本语法学习笔记之面向对象:接口

wolgame · · 1275 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

Go语言的接口并不是其他语言(C++、Java、C#等)中所提供的接口概念。

基于模块设计的单向依赖原则,模块A在实现自身的业务时,不应该关心某个具体使用方的要求。模版A实现的时候,甚至不知道会有如今B来使用它。

非侵入式接口

在Go语言中,一个类只需要实现了接口要求的所有函数,我们就说这个类实现了该接口
type File struct {
     // ...
}
func (f *File) Read(buf []byte) (n int, err error)
func (f *File) Write(buf []byte) (n int, err error)
func (f *File) Seek(off int64, whence int) (pos int64, err error)
func (f *File) Close() error
File类实现了4个方法
如有接口:
type IFile interface {
    Read(buf []byte) (n int, err error)
    Write(buf []byte) (n int, err error)
    Seek(off int64, whence int) (pos int64, err error)
    Close() error
}
type IReader interface {
   Read(buf []byte) (n int, err error)
}
type IWriter interface {
    Write(buf []byte) (n int, err error)
}
type ICloser interface {
    Close() error
}
尽管File类并没有从这些接口继承,甚至可以不知道这些接口的存在,但是File类实现了这些接口,可以进行赋值:
var file1 IFile = new(File)
var file2 IReader = new(File)
var file3 IWriter = new(File)
var file4 ICloser = new(File)
因为File类实现 接口 要求的 所有方法

接口赋值

接口赋值在Go语言中分为如下两种情况:
  1. 将对象实例赋值给接口;
  2. 将一个接口赋值给另一个接口。
type Integer int
<pre name="code" class="plain">func (a Integer) Less(b Integer) bool {
   return a < b
}
func (a *Integer) Add(b Integer) { *a += b}

定义接口
type LessAdder interface {
    Less(b Integer) bool
    Add(b Integer)
}
var a Integer = 1
var b LessAdder = &a ... (1)ok    <span style="font-family: Arial, Helvetica, sans-serif;">
</span>var b LessAdder = a ... (2)no
</pre><pre name="code" class="plain">GO可以根据
func (a Integer) Less(b Integer) bool
自动生成新方法
func (a *Integer) Less(b Integer) bool {
      return (*a).Less(b)
}
接口赋值并不要求两个接口必须等价。如果接口A的方法列表是接口B的方法列表的子集,那么接口B可以赋值给接口A。

接口查询

var file1 Writer = ...
if file5, ok := file1.(two.IStream); ok {
    ...
}
这个if语句检查file1接口指向的对象实例是否实现了two.IStream接口。

       在Go语言中,你可以询问接口它指向的对象是否是某个类型,比如:
var file1 Writer = ...
if file6, ok := file1.(*File); ok { //这个if语句判断file1接口指向的对象实例是否是*File类型
    ...
}

类型查询

在Go语言中,还可以更加直截了当地询问接口指向的对象实例的类型,例如:
var v1 interface{} = ...
switch v := v1.(type) {
     case int: // 现在v的类型是int
     case string: // 现在v的类型是string
     ...
}

接口组合

//接口中可以组合其它接口,这种方式等效于在接口中添加其它接口的方法
type Reader interface {
	read()
}
type Writer interface {
	write()
}

//定义上述两个接口的实现类
type MyReadWrite struct{}

func (mrw *MyReadWrite) read() {
	fmt.Println("MyReadWrite...read")
}

func (mrw *MyReadWrite) write() {
	fmt.Println("MyReadWrite...write")
}

//定义一个接口,组合了上述两个接口
type ReadWriter interface {
	Reader
	Writer
}

//上述接口等价于:
type ReadWriterV2 interface {
	read()
	write()
}

//ReadWriter和ReadWriterV2两个接口是等效的,因此可以相互赋值
func interfaceTest0104() {
	mrw := &MyReadWrite{}
	//mrw对象实现了read()方法和write()方法,因此可以赋值给ReadWriter和ReadWriterV2
	var rw1 ReadWriter = mrw
	rw1.read()
	rw1.write()

	fmt.Println("------")
	var rw2 ReadWriterV2 = mrw
	rw2.read()
	rw2.write()

	//同时,ReadWriter和ReadWriterV2两个接口对象可以相互赋值
	rw1 = rw2
	rw2 = rw1
}

Any类型

由于Go语言中任何对象实例都满足空接口interface{},所以interface{}看起来像是可以指向任何对象的Any类型,如下:
var v1 interface{} = 1 // 将int类型赋值给interface{}
var v2 interface{} = "abc" // 将string类型赋值给interface{}
var v3 interface{} = &v2 // 将*interface{}类型赋值给interface{}
var v4 interface{} = struct{ X int }{1}
var v5 interface{} = &struct{ X int }{1}










有疑问加站长微信联系(非本文作者)

本文来自:CSDN博客

感谢作者:wolgame

查看原文:go基本语法学习笔记之面向对象:接口

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:701969077

1275 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传