free0day 2020-04-11
Golang-面向对象编程三大特性-继承
继承基本介绍和示意图
继承可以解决代码复用,让我们的编程更加靠近人类思维。
当多个结构体存在相同的属性(字段)和方法时,可以从这些结构体中抽象出结构体(比如刚才的Student),在该结构体中定义这些相同的属性和方法。
其它的结构体不需要重新定义这些属性(字段)和方法,只需嵌套一个 Student 匿名结构体即可。 [画出示意图]
也就是说:在 Golang 中,如果一个 struct 嵌套了另一个匿名结构体,那么这个结构体可以直接访问匿名结构体的字段和方法,从而实现了继承特性。
嵌套匿名结构体的基本语法
type Goods struct {
Name string
Price int
}
type Book struct {
Goods //这里就是嵌套匿名结构体 Goods Writer string
}
案例
我们对 extends01.go 改进,使用嵌套匿名结构体的方式来实现继承特性,请大家注意体会这样编程的好处
type Student struct { Name string Age int Score float64 } func (student *Student) ShowInfo() { fmt.Printf("学生名=%v 年龄=%v 成绩=%v\n",student.Name,student.Age,student.Score) } func (student *Student) SetScore(score float64) { student.Score = score } type Pupil struct { Student } func (pupil *Pupil) Testing() { fmt.Println("考试的内容不一样,正在考试中.....\n") } type Graduate struct { Student } func (graduate *Graduate) Testing() { fmt.Println("考试的内容不一样,正在考试中.....\n") }
继承给编程带来的便利
1)代码的复用性提高了
2)代码的扩展性和维护性提高了
继承的深入讨论
1)结构体可以使用嵌套匿名结构体所有的字段和方法,即:首字母大写或者小写的字段、方法, 都可以使用。【举例说明】
2)匿名结构体字段访问可以简化,如图
对上面的代码小结
(1)当我们直接通过 b 访问字段或方法时,其执行流程如下比如 b.Name
(2)编译器会先看 b 对应的类型有没有 Name, 如果有,则直接调用 B 类型的 Name 字段
(3)如果没有就去看 B 中嵌入的匿名结构体 A 有没有声明 Name 字段,如果有就调用,如果没有继续查找..如果都找不到就报错.
3)当结构体和匿名结构体有相同的字段或者方法时,编译器采用就近访问原则访问,如希望访问匿名结构体的字段和方法,可以通过匿名结构体名来区分【举例说明】
4)结构体嵌入两个(或多个)匿名结构体,如两个匿名结构体有相同的字段和方法(同时结构体本身没有同名的字段和方法),在访问时,就必须明确指定匿名结构体名字,否则编译报错。【举例说明】
5)如果一个 struct 嵌套了一个有名结构体,这种模式就是组合,如果是组合关系,那么在访问组合的结构体的字段或方法时,必须带上结构体的名字
6)嵌套匿名结构体后,也可以在创建结构体变量(实例)时,直接指定各个匿名结构体字段的值
t练习结构体的匿名字段是基本数据类型,如何访问, 下面代码输出什么
说明
1)如果一个结构体有 int 类型的匿名字段,就不能第二个。
2)如果需要有多个 int 的字段,则必须给 int 字段指定名字
面向对象编程-多重继承
多重继承说明
如一个 struct 嵌套了多个匿名结构体,那么该结构体可以直接访问嵌套的匿名结构体的字段和方法,从而实现了多重继承。
案例演示
通过一个案例来说明多重继承使用
多重继承细节说明
1)如嵌入的匿名结构体有相同的字段名或者方法名,则在访问时,需要通过匿名结构体类型名来区分。【案例演示】
2)为了保证代码的简洁性,建议大家尽量不使用多重继承