1、类型方法的实例成员复制与类型方法的实例成员引用
在Go中能够相似Java等面向对象语言必定为某个对象定义方法,可是Go中并无类的存在,能够不严格的将Go中的struct类型理解为面向对象中的类;函数
type demoObject struct { id int }
类的概念有了,那怎么为这个类(struct结构)定义方法呢;Go语言中有两种方式:
一、在类型指针上定义方法;指针
func (o *demoObject) one() { fmt.Printf("one方法字段的内存地址:%x\n", unsafe.Pointer(&o.id)) }
二、在类型上定义方法;code
func (o demoObject) two() { fmt.Printf("one方法字段的内存地址:%x\n", unsafe.Pointer(&o.id)) }
这两种方式其实定义方式都差很少,区别只是在于方法时定义在类型上仍是定义在类型指针上面,就是由于这点区别致使了方法中类型实例有了本质的区别;
在类型上定义方法其类型实例的成员值会进行复制,也就是说每一个该类型实例的方法中类型的成员地址也都不同;
而在类型指针上定义方法其类型实例的成员只是指针复制,全部类型指针上方法的类型成员地址彻底同样;对象
var obj = new(demoObject) fmt.Printf("main函数obj对象字段的内存地址:%x\n", unsafe.Pointer(&obj.id)) obj.one() obj.two()
one方法:o实例的成员id内存地址与obj实例的成员id地址同样
two方法:o实例的成员id内存地址与obj实例的成员id地址不同
总结来讲:
one方法中修改demoObject类型的成员id的值obj实例成员id值也会变化
two方法中修改demoObject类型的成员id的值obj实例成员id值不会变化继承
2、接口与实现
在Go中实现某接口不须要显式的依赖该接口,只须要在某类型或类型指针上定义与该接口的方法签名彻底一致的接口便可;接口
type inter interface { hello() } func (o *demoObject) hello() { } var i inter = new(demoObject) i.hello()
如上代码所示,便可说类型demoObject实现了inter接口,Go的接口具备非入侵性,因为该特性所以Go语言也具备了dock typing ,也就是鸭子类型;内存
3、内嵌类型(相似继承并不是等同于Java中的继承)
Go中存在这一种匿名内嵌类型,经过匿名内嵌类型能够获得相似与继承的结果;引用
type base struct { Id int } type level struct { *base } var l=new(level) fmt.Println(l.Id)
如上代码所示,经过在类型level中引入匿名内嵌类型base,可使用level类型的实例l调用获得类型base中的成员Id,若是base类型有绑定方法level类型实例同样能够调用该方法。
请注意上面说的是经过内嵌类型能够获得的是相似继承,并不是等同于继承,level实例虽然能够访问获得base类型实例,但并不能在level中重写base的方法。二者并不是继承与被继承的关系;方法
4、Go中的多态
Go有接口的存在,是否也存在多态的概念呢。 答案是存在的以下代码所示,与Java中的多态并无很大区别;总结
type one struct{} type two struct{} type inter interface { hello() } func (o *one) hello() { fmt.Println("one hello") } func (t *two) hello() { fmt.Println("two hello") } func say(i inter) { i.hello() } var o = new(one) var t = new(two) say(o) say(t)
Golang中存在面向对象的某些特征,但又与传统的面向对象语言有着不小区别;如Go中只有相似继承功能,又不等同于其余语言的继承,没法重写方法,也不存在子类于父类的概念;Go中存在接口但空接口表明着是任意类型于Java中的Object类相似但又不同;