内嵌与聚合: 外部类型只包含了内部类型的类型名, 而没有field 名, 则是内嵌。 外部类型包含了内部类型的类型名,还有filed名,则是聚合。聚合的在JAVA和C++都是常见的方式。而内嵌则是GO 的特有方式。
type Base struct {
basename string
}
type Derive struct { ---内嵌
Base
}
type Derive struct { 内嵌, 这种内嵌与上面内嵌的区别是什么,后面详细介绍
*Base
}
type Derive struct{ 聚合
base Base
}
内嵌的方式: 主要是通过结构体和接口的组合,有四种。
接口中内嵌接口 : 这里的做为内嵌接口的含义实际上还是指的一个定义,而不是接口的一个实例,相当于合并了两个接口定义的函数,只有同时了Writer和 Reader 接口,是可以说是实现了WRer接口,即才可以作为WRer的实例。
type Writer interface{
Write()
}
type Reader interface{
Read()
}
type WRer interface{
Reader
Writer
}
***********************************************************************************************************************
在接口中内嵌struct : 存在语法错误,并不具有实际的含义, 编译报错./person.go:22: interface contains embedded non-interface Person
Interface 不能嵌入非interface的类型。
*********************************************************************************************************************************
在结构体(struct)中内嵌 接口(interface)
1, 初始化的时候,内嵌接口要用一个实现此接口的结构体赋值
2,外层结构体中,只能调用内层接口定义的函数。 这是由于编译时决定。
3,外层结构体,可以作为receiver,重新定义同名函数,这样可以覆盖内层内嵌结构中定义的函数
4,如果上述第3条实现,那么可以用外层结构体引用内嵌接口的实例,并调用内嵌接口的函数
Type Printer interface{
Print()
}
Type CanonPrinter struct{
Printname string
}
Func (printer CanoPrinter) Print(){
Fmt.Println(“this iscannoprinter printing now”)
}
Type PrintWorker struct{
Printer
name string
age int
}
// 如果没有下面实现,则
Func (printworker PrintWorker) Print(){
Fmt.Println(“thisis printing from PrintWorker)
printworker.Printer.Print() // 这里 printworker 首先引用内部嵌入Printer接口的实例,然后调用Printer 接口实例的Print()方法
}
Func main(){
canon := CanonPrinter(“canoprint_num_1”)
printworker := PrintWorker{Printer:canon,name: “ansendong”, age: 34}
printworker.Print() //如果没有上述红色部分的实现,则这里只调用CanonPrinter实现的Print()方法。
}
**********************************************************************************************************************************
结构体(struct)中内嵌 结构体(struct)
1, 初始化,内嵌结构体要进行赋值
2,外层结构自动获得内嵌结构体所有定义的field和实现的方法(method)
3, 同上述结构体中内嵌接口类似,同样外层结构体可以定义同名方法,这样覆盖内层结构体的定义的方法。 同样也可以定义同名变量,覆盖内层结构体的变量
4,同样可以内层结构体引用,内层结构体重已经定义的方法和变量。