一、go 面向对象继承: B继承A, 即在B结构体中 声明 A匿名结构体
1.结构体可以使用嵌套匿名结构体的所有字段加方法(即:同一个包中,首字母大写和小写的字段、方法,都可以使用)
2.匿名结构体的字段和方法访问,调用可以简化, A.B.Name A.Name。但是当结构体中有与匿名结构体中相同的方法时,情况就不同
3.当结构体和你们结构体有相同的字段或者方法时,编译器采用的是“就近访问原则”访问,如果希望访问匿名结构体中的字段或方法,可以通过匿名结构体名称来区分。
当我们使用结构体中的方法时,如果结构体中没有,则底层会去匿名结构体中找相同的方法,如果结构体和匿名结构体都有,那么就使用当前结构体的方法。
package main
import "fmt"
type Person struct {
Name string
age int
}
func (p *Person) SayHello() {
fmt.Println(p.Name,"say hello")
}
func (p *Person) GetName() {
fmt.Println("(Person)I am",p.age,"years old")
}
func (p *Person) run() {
fmt.Println(p.Name,"run")
}
type Student struct{
Person
}
func (s *Student) GetName() {
fmt.Println("(Sstudent)I am",s.age,"years old")
}
func main() {
var stu Student
stu.Person.Name = "jack"
stu.Person.age = 18
stu.Person.SayHello()
stu.Person.GetName()
stu.Person.run()
fmt.Println("_________________________________")
stu.Name = "tom"
stu.age = 20
stu.SayHello()
stu.GetName()
stu.run()
}
二、go继承可以多继承,当继承的两个或多个匿名结构体中有相同的字段或方法,而结构体中没有对应的字段和方法,那么,就需要通过匿名结构体名进行访问,明确取值。
package main
import (
"fmt"
)
type A struct {
Name string
}
func (a *A) Say() {
fmt.Println("A name is",a.Name)
}
type B struct {
Name string
}
func (b *B) Say() {
fmt.Println("A name is",b.Name)
}
type C struct {
A
B
}
func main() {
var c C
c.A.Name = "aaa"
c.B.Name = "bbb"
c.A.Say()
c.B.Say()
//c.Name //报错
//c.Say() //报错
}
三、go在多继承中,可以继承匿名结构体指针,在赋值匿名结构体时,需要用取址符 &,
package main
import (
"fmt"
)
type A struct {
Name string
}
func (a *A) Say() {
fmt.Println("A name is",a.Name)
}
type B struct {
Name string
}
func (b *B) Say() {
fmt.Println("A name is",b.Name)
}
type C struct {
*A
*B
}
func main() {
c := C{&A{Name: "JACK"},&B{Name: "TOM"}}
fmt.Println(c.A)
fmt.Println(c.B)
fmt.Println(*c.A)
fmt.Println(*c.B)
fmt.Println(c.A.Name)
fmt.Println(c.B.Name)
}
四、如果一个结构体中嵌入了一个有名结构体,这种模式就是组合模式,是组合关系。那么就在访问组合结构体的字段和方法时,必须带上结构体的名字(结构体变量名)
package main
import (
"fmt"
)
type A struct {
Name string
}
func (a *A) Say() {
fmt.Println("A name is",a.Name)
}
type B struct {
a A
}
func main() {
var b = B{A{Name: "JACK"}}
fmt.Println(b.a.Name)
fmt.Println(b.Name) //报错
}