Go 面向对象编程之继承

标签: Golang基础  go  golang

面向对象编程之继承

  • 看一个问题,引出继承的必要性
    • 一个小问题,看个学生考试系统的程序 ,提出代码复用的问题
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()
}
  • 对上面代码的小结
    • Pupil 和 Graduate 两个结构体的字段和方法几乎,但是我们却写了相同的代码, 代码复用性不强
    • 出现代码冗余,而且代码不利于维护,同时也不利于功能的扩展。
    • 解决方法-通过继承方式来解决

继承基本介绍和示意图

  • 继承可以解决代码复用,让我们的编程更加靠近人类思维。
  • 当多个结构体存在相同的属性(字段)和方法时
    • 可以从这些结构体中抽象出结构体(比如刚才的Student)
    • 在该结构体中定义这些相同的属性和方法。
  • 其它的结构体不需要重新定义这些属性(字段)和方法,只需嵌套一个 Student 匿名结构体即可。
  • 示意图如下:

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

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

type Goods struct {
    Name string
    Price int
}
type Book struct {
    Goods    -- 这里就是嵌套匿名结构体 Goods
    Writer string
}

演示案例

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))
}
  • 输出结果:

  • 继承给编程带来的便利
    • 代码的复用性提高了
    • 代码的扩展性和维护性提高
版权声明:本文为baidu_41388533原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/baidu_41388533/article/details/107117777