前言:
接着上一次的“接口”内容说起,Go语言并不是其他的语言(C++,java,C#)中提供的接口概念。在Golang出现之前,接口主要是作为不同组件之间的七月存在。契约的实现时强制的,必须确定声明了这个接口。为了实现接口必须继承接口(侵入式)。
正文:
在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类,并实现Read(),Write(),Seek(),Close()等方法。设想我们有如下接口:
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{ Writer(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 IWrite = new (File) var file4 ICloser= new (File)
接口赋值:
接口赋值在Go语言中分为两种情况: 1.将对象实例赋值给接口。2.将一个接口赋值给另一个接口。
(1)将某类型对象实例赋值给一个接口,这要求该对象实现所有方法。
type Integer int func (a Iterger) Less (b Integer)bool{ return a<b } func (a *Integer) Add (b Integer) Add(b Integer){ *a += b } //接下来定义接口LessAdder type LessAdder interface{ Less(b Integer)bool Add(b Integer) }
我们定义一个Integer类型的对象实例,怎么赋值给LessAdder接口
var a Integer=1 var b LessAdder= &a (一) var b LessAdder =a (二)
Go语言的接口应用语句(一),原因如下 Go语言可以根据下面的函数
func (a Integer) Less(b Interger) bool{ return (*a).Less(b) }//自动生成一个新Less()方法
类型*Integer既存在Less()方法,也存在Add()方法,满足LessAdder接口,而另方面来说,根据func (a *Integer) Add (b Integer) 这个函数无法自动生成下面的成员方法
func (a Integer) Add (b Integer){ (&a).Add(b) }
因为(&a).Add()改变的只是参数a,对外部实际操作的对象并无影响,这不符合用户的预期,所以Go语言不会自动生成函数。因此,类型Integer只存在Less()方法,缺少Add()方法,不满足LessAdder接口,所以语句(二)不能完成赋值。 //表示目前无法理解,刚才补了一下c语言知识 = =
让我们看一下另一个情况:将接口赋值给另一个接口,在Golang中只要两个接口实现了相同的方法就可以相互赋值。接下来:
package one type ReadWrite interface{ Read(buf []byte) (n int,err error) Write(buf []byte) (n int,err error) } //第二个接口位于two包中 package two type IStream interface{ Write(buf []byte) (n int,err error) Read(buf []byte) (n int,err error) }
如果A方法受在下hiB方法的列表子集,那么接口B可以赋值给接口A假设我们有如下接口
type Write interface{ Write(buf []byte) (n int,err ,error) }
就可以将上面的one.ReadWriter和tow.IStream的实例赋值给接口,反之不可以。
接口查询:
有什么办法才能让上面的Writer接口转换为two.IStream接口么?其实接下来的接口查询就包含这些内容。
var file1 Write =new(File); //查看此接口是否指向FILE if file2,ok:=file1.(*File);ok{ .... }
var file1 Write =new(File); //查看此接口是否实现了FILE if file2,ok:=file1.(File);ok{ .... }
类型查询
在Go语言中,还可以直接的询问接口指向的类型,如下:
var v1 interface{}=new(File) switch v:=v1.(type){ case int : //为int case string : //为string ... }
Any类型:
没错Any类型就是空接口 interface{},可以指向任何Any类型
例如fmt库中的PrintXXX函数
func Printf(fmt string,arg ...interface{})
后记:
今天内容过多,明天会学习一个完整的实例,逐步学习和理解Golang中面向对象的特征。PS:书中是实现一个播放器流程。
a1