go中继承基本使用

一 继承的引出

学生考试系统引出代码复用问题。

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) testing() {
   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) testing() {
   fmt.Println("大学生正在考试中.....")
}

// 代码冗余
func main() {
   var pupil = &Pupil{
      Name: "tom",
      Age:  10,
   }
   pupil.testing()
   pupil.SetScore(90)
   pupil.ShowInfo()

   var graduate = &Graduate{
      Name: "mary",
      Age:  20,
   }
   graduate.testing()
   graduate.SetScore(90)
   graduate.ShowInfo()
}

2 测试

小学生正在考试中.....

学生名=tom 年龄=10 成绩=90

大学生正在考试中.....

学生名=mary 年龄=20 成绩=90

3 分析

a Pupil 和 Graduate 两个结构体的字段和方法几乎一样,但是却写了相同的代码,代码复用性不强。

b 出现代码冗余,而且代码不利于维护,同时也不利于功能的扩展。

c 通过继承方式可以解决该问题。

二 继承基本介绍

1 继承可以解决代码复用,让编程更加靠近人类思维。

2 当多个结构体存在相同的属性(字段)和方法时,可以从这些结构体中抽象出结构体(比如 Student ),在该结构体中定义这些相同的属性和方法。

3 其它的结构体不需要重新定义这些属性(字段)和方法,只需嵌套一个 Student 匿名结构体即可。

go中继承基本使用_第1张图片

4 在 Golang 中,如果一个 struct 嵌套了另一个匿名结构体,那么这个结构体可以直接访问匿名结构体的字段和方法,从而实现了继承特性。

三 嵌套匿名结构体的基本语法

type Goods struct {

    Name string

    Price int

}

type Book struct {

    Goods // 这里就是嵌套匿名结构体 Goods

    Writer string

}

四 快速入门

1 要求

对开篇提出的问题进行改进,使用嵌套匿名结构体的方式来实现继承特性。

2 代码

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
}

// 给 *Student 增加一个方法,那么 Pupil 和 Graduate 都可以使用该方法
func (stu *Student) GetSum(n1 int, n2 int) int {
   return n1 + n2
}

// 小学生
type Pupil struct {
   Student // 嵌入了 Student 匿名结构体
}

// 显示他的成绩
// 这是 Pupil 结构体特有的方法
func (p *Pupil) testing() {
   fmt.Println("小学生正在考试中.....")
}

// 大学生
type Graduate struct {
   Student //嵌入了 Student 匿名结构体
}

// 显示他的成绩
// 这是 Graduate 结构体特有的方法
func (p *Graduate) testing() {
   fmt.Println("大学生正在考试中.....")
}

func main() {
   // 当我们对结构体嵌入了匿名结构体,使用方法会发生变化
   pupil := &Pupil{}
   pupil.Student.Name = "tom~"
   pupil.Student.Age = 8
   pupil.testing()
   pupil.Student.SetScore(70)
   pupil.Student.ShowInfo()
   fmt.Println("res=", pupil.Student.GetSum(1, 2))


   graduate := &Graduate{}
   graduate.Student.Name = "mary~"
   graduate.Student.Age = 28
   graduate.testing()
   graduate.Student.SetScore(90)
   graduate.Student.ShowInfo()
   fmt.Println("res=", graduate.Student.GetSum(10, 20))
}

3 测试

小学生正在考试中.....

学生名=tom~ 年龄=8 成绩=70

res= 3

大学生正在考试中.....

学生名=mary~ 年龄=28 成绩=90

res= 30

五 继承给编程带来的便利

1 代码的复用性提高了。

2 代码的扩展性和维护性提高了。

你可能感兴趣的:(Go,go)