持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第44天,点击查看活动详情
一、为什么需要继承
1.1 案例
package main
import (
"fmt"
)
// 编写一个考试系统
//小学生
type Pupil struct {
Name string
Age int
Score int
}
// 显示成绩方法
func (p *Pupil) ShowInfo() {
fmt.Printf("学生名字:%v, 年龄:%v, 成绩:%v \n", p.Name, p.Age, p.Score)
}
// 设置成绩
func (p *Pupil) SetScore(score int) {
p.Score = score
}
func (p *Pupil) Exam() {
fmt.Println("小学生正在考试........")
}
// 大学生
type Graduate struct {
Name string
Age int
Score int
}
// 显示成绩方法
func (p *Graduate) ShowInfo() {
fmt.Printf("学生名字:%v, 年龄:%v, 成绩:%v \n", p.Name, p.Age, p.Score)
}
// 设置成绩
func (p *Graduate) SetScore(score int) {
p.Score = score
}
func (p *Graduate) Exam() {
fmt.Println("大学生正在考试........")
}
func main() {
//
var p = &Pupil{
Name: "力王",
Age: 10,
}
// 小学生正在考试........
p.Exam()
p.SetScore(95)
// 学生名字:力王, 年龄:10, 成绩:95
p.ShowInfo()
// 大学生
var g = &Graduate{
Name: "大力王",
Age: 20,
}
// 大学生正在考试........
g.Exam()
g.SetScore(150)
// 学生名字:大力王, 年龄:10, 成绩:95
g.ShowInfo()
}
1.2 案例解析
- Pupil 和 Graduate 两个结构体字段和方法几乎一样,但是在声明使用时却写了同样的代码
- 出现代码冗余,不利于代码维护,不利于功能拓展
- 解决方法:
继承方法实现
1.3 继承基本介绍
- 继承可以解决代码复用,让我们的编程更加靠近人类思维。
- 当多个结构体存在相同的属性(字段)和方法时,可以从这些结构体中抽象出结构体(比 如刚才的Student),在该结构体中定义这些相同的属性和方法。
- 其它的结构体不需要重新定义这些属性和方法,只需嵌套一个Student匿名结构体即 可。
- 也就是说:在Golang中,如果-一个struct嵌套了另一个匿名结构体,那么这个结构
体可以直接访问匿名结构体的字段和方法,从而实现了
继承特性
。
1.4 基本语法
type Goods struct{
Name string
Price int
}
type Book struct{
Goods //嵌套匿名结构体Goods
Writer string
}
1.5 快速入门案例(改进1.1)
package main
import (
"fmt"
)
// 编写一个考试系统
//
type Student struct {
Name string
Age int
Score int
}
// 将 Pupil 和 Graduate共有的方法绑定到 *Student
func (stu *Student) ShowInfo() {
fmt.Printf("学生名字:%v, 年龄:%v, 成绩:%v \n", stu.Name, stu.Age, stu.Score)
}
func (stu *Student) SetScore(Score int) {
stu.Score = Score
}
func (stu *Student) GetScore() int {
return stu.Score
}
func (stu *Student) getSum(x int, y int) int {
return x + y
}
//小学生
type Pupil struct {
Student // 嵌入匿名结构体
}
// 显示成绩方法
// 这是特有方法,保留
func (p *Pupil) Exam() {
fmt.Println("小学生正在考试........")
}
// 大学生
type Graduate struct {
Student // 嵌入匿名结构体
}
// 显示成绩方法
// 这是特有方法,保留
func (p *Graduate) Exam() {
fmt.Println("大学生正在考试........")
}
func main() {
//
pupil := &Pupil{}
pupil.Student.Name = "小力王"
pupil.Student.Age = 8
// 小学生正在考试........
pupil.Exam()
// 设置小学生分数
// 小学生正在考试........
// 学生名字:小力王, 年龄:8, 成绩:88
pupil.Student.SetScore(88)
pupil.Student.ShowInfo()
graduate := &Graduate{}
graduate.Student.Name = "大力王"
graduate.Student.Age = 22
// 大学生正在考试........
// 学生名字:大力王, 年龄:22, 成绩:149
graduate.Exam()
graduate.Student.SetScore(149)
graduate.Student.ShowInfo()
// 测试Student里面的getSum
// Student GetSum = 30
fmt.Println("Student GetSum = ", pupil.Student.getSum(10, 20))
}
1.6 继承的好处
- 提高代码复用性
- 提高代码的扩展性和维护性