Golang //学习笔记 面向对象编程(二)

golang cyanprobe 8年前 (2016-07-26) 3348次浏览 已收录 0个评论

前言:

接着上一次的“接口”内容说起,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


CyanProbe , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:Golang //学习笔记 面向对象编程(二)
喜欢 (1)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址