interface 理论
接口是一个或多个方法签名的集合
只要某个类型拥有该接口的所有方法签名,即算实现该接口,无需显示声明实现了哪个接口,这称为Structural Typing
接口只有方法声明,没有实现,没有数据字段
接口可以匿名嵌入其他接口,或嵌入到结构中
将对象赋值给接口时,会发生拷贝,而接口内部存储的是指向这个复制品的指针,即无法修改复制品的状态,也无法获取指针
只有当接口存储的类型和对象都为nil时,接口才等于nil
接口调用不会做receiver的自动转换
接口同样支持匿名字段方法
接口也可实现类似OOP中的多态
空接口可以作为任务类型数据的容器
举例
1、创建接口
// interface 接口 练习
//实现接口的原则就是
//实现了它定义的方法,就默认是实现了接口
package main
import "fmt"
//声明一个接口
type USB interface {
//声明方法Name, 并设置 返回值类型string
Name() string
//声明方法Connect方法,无返回值
Connect()
}
//声明一个类型,在Go语言中,对应的就是struct类型
type PhoneConnector struct {
//声明一个私有属性
name string
}
//---------------------声明完Name,Connector方法后,就是实现了USB接口了---------------------------
//使用receiver,将类型跟方法进行绑定
func (pc PhoneConnector)Name() string{
return pc.name
}
func (pc PhoneConnector)Connector() {
fmt.Println("connected:\t", pc.name)
}
//--------------------------------------------------------------------------------------
func main() {
a := PhoneConnector{"apple"}
fmt.Println("Name:\t", a.Name())
a.Connector()
}
2、接口之间的嵌套 练习
//interface 嵌套 练习测试
package main
import "fmt"
//定义一个空的接口
//这样的话,所有的类,都默认实现了这个接口,因为它没有方法
//定义的空接口,就相当于定义了一 个Object对象,最高层
//都是它的子类了,就没有任何限制了
type nullEmpty interface {
}
// 定义一个 父接口
type HOME interface {
//这个接口里,只定义一个方法
Name() string
}
//再定义一个接口, 这相当于是子接口了
type MyHome interface {
Show() string
//这样就嵌套了 一个接口
HOME
}
//声明一个结构类型
type BeijingHome struct {
name string
}
//-----------开始创建方法method-----
func (info BeijingHome)Show(){
fmt.Println("Show()--->info.name:\t", info.name)
}
func (info BeijingHome)Name() string{
return info.name
}
func main() {
a := BeijingHome{"yihuyuan"}
fmt.Println("name:\t", a.Name())
a.Show()
//------下面演示一下,上面理论中说的---复制品的问题----
b := a
b.name = "lenovo" //修改后,并没有修改a里的值
b.Show()
Disconnect(a)
Disconnect2(a)
}
//设计一个简单的类型断言
func Disconnect(home HOME){
if pc, ok := home.(BeijingHome); ok{
fmt.Println("Disconnected:\t", pc.name)
return
}
fmt.Println("Unknown decive.")
}
//设计一个简单的类型断言
//传入的参数,是,空接口
//实际上,对于传入的参数,就没有限制了
func Disconnect2(home interface{}){
//对Disconnect()方法,进行改造,
//因为,传入的参数是顶层,相当于Java里的Object,没有任何限制
//类型,需要自己判断
switch v := home.(type) {
case BeijingHome:
fmt.Println("Disconnected:\t", v.name)
default:
fmt.Println("Unknown decive.")
}
}
3、不同接口之间的转换
//不同接口之间的转换,类似于Java中的向上转型,或者向下转型
//就是说,有两个接口A, B
//其中,A接口里,嵌入了B
//那么A接口可以转换成B接口,但是,B接口不能转换成A接口,因为
//A接口里,可能包含B接口里没有的方法
//也就是说,多的可以向少的转换,反之不可。
package main
import "fmt"
type USB2 interface {
Name() string
Connecter
}
type Connecter interface {
Connect()
}
type PcConnecter struct {
name string
}
func (pcConnecter PcConnecter)Name() string {
return pcConnecter.name
}
func(pcConnecter PcConnecter)Connect() {
fmt.Println("Connected:\t", pcConnecter.name)
}
func main() {
pc := PcConnecter{"appleConnector"}
var a Connecter
//将USE2 类型,强制 转换成了Connecter类型
a = Connecter(pc)
a.Connect()
//------验证----只有当接口存储的类型和对象都为nil时,接口才等于nil
//声明一个空接口, 也没有赋值,就是nil
var aa interface{}
fmt.Println( aa == nil) // aa 本身就是一个nil,啥也没存
//变量p, 是一个指向int类型的指针
//直接初始化为nil
var p *int = nil
aa = p //aa 指向p
fmt.Println( aa == nil)
}
©著作权归作者所有:来自51CTO博客作者故新的原创作品,如需转载,请注明出处,否则将追究法律责任