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

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}









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值