GO语言使用之面向对象编程(6)面向对象三大特征之继承

一、为什么需要继承

1、继承基本介绍
1)继承可以解决代码复用,让我们的编程更加靠近人类思维。
2)当多个结构体存在相同的属性(字段)和方法时,可以从这些结构体中抽象出结构体(比如刚才的Student),在该结构体中定义这些相同的属性和方法。
3)其它的结构体不需要重新定义这些属性(字段)和方法,只需嵌套一个Student匿名结构体即可。
2、示意图
这里写图片描述
也就是说:在Golang中,如果一个struct嵌套了另一个匿名结构体,那么这个结构体可以直接访问匿名结构体的字段和方法,从而实现了继承特性。

二、如何使用继承

1、继承基本语法
在GO中通过嵌套匿名结构体实现继承。

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

三、快速入门案例

//继承快速入门案例
type student struct {
    name string
    age int
    score float64
}
func (s *student) setGrade(score float64)  {
    s.score=score
}  
func (s *student) showInfor()  {
    fmt.Printf("学生信息如下:姓名:%s 年龄:%d  分数:%f \n",
                s.name,s.age,s.score)
}

type collegeStudent struct{
    student
    writeThesis bool
}
type middleStudent struct{
    student
    college bool
}

type middleStudentPoint struct{
    *student
    college bool
}

func (c *collegeStudent) graduation()  {
    res := "未毕业"
    if c.writeThesis {
        res = "已毕业"
    }

    fmt.Printf("毕业信息如下:姓名:%s 年龄:%d  分数:%f 是否毕业: %s\n",
        c.name,c.age,c.score,res)
}

func (p *primaryStudent) showInfor()  {
    fmt.Printf("学生信息如下:姓名:%s 年龄:%d  分数:%f \n",
    p.name,p.age,p.score)
}
func ExtendDemo()  {
    // 匿名结构体字段访问可以简化
    /*继承结构体的声明方式1*/
    var college collegeStudent
    college.score = 70.5
    college.name = "张三"
    college.age = 23
    college.showInfor()
    college.student.setGrade(59.1)
    college.showInfor()
    college.writeThesis = true
    college.graduation()
    /*继承结构体(匿名结构体)的声明方式2*/
    middle := middleStudent{
        student : student{
            name : "王辉",
            age : 44,
            score : 50,
        },
        college :true,
    }
    /*继承结构体的声明方式3*/
    middle1 := middleStudent{
         student{ "王辉",44,90,},true,
    }

    middle.showInfor()
    middle1.showInfor()
    /*指针*/
  /*继承结构体的声明方式4*/
  middlep :=middleStudentPoint{&student{ "刘亦菲",44,90,},true,}
  /*继承结构体的声明方式5*/
  middlep1 :=middleStudentPoint{
         student : &student{
                name : "小龙女",
                age : 44,
                score : 50,
            },
        college :true,}
        middlep.showInfor()
        middlep1.showInfor()
}

四、继承给编程带来的便利

1、代码的复用性提高了
2、代码的扩展性和维护性提高了

五、继承使用细节和注意事项

1、结构体可以使用嵌套匿名结构体所有的字段和方法,即:首字母大写或者小写的字段、方法,都可以使用。

type student struct {
    name string
    age int
    score float64
}
func (s *student) setGrade(score float64)  {
    s.score=score
}  
func (s *student) showInfor()  {
    fmt.Printf("学生信息如下:姓名:%s 年龄:%d  分数:%f \n",
                s.name,s.age,s.score)
}
type collegeStudent struct{
    student
    writeThesis bool
}
func ExtendDemo()  {

    var college collegeStudent
    college.score = 70.5
    college.name = "张三"
    college.age = 23
    college.showInfor()
    college.student.setGrade(59.1)
    college.showInfor()
    }

2、匿名结构体字段访问可以简化。

    college.score = 70.5
    college.student.name = "张三"

使用简化的方法区访问字段或者方法的流程
(1) 先到本身结构体去找字段或者方法,如果找到,就直接调用
(2) 如果找不到,就到匿名结构体去找,如果找到就调用,否则继续向上找。
(3) 如果一直找不到,则报错

3、当结构体和匿名结构体有相同的字段或者方法时,编译器采用就近访问原则访问,如希望访问匿名结构体的字段和方法,可以通过匿名结构体名来区分【案例演示】

/*
当结构体和匿名结构体有相同的字段或者方法时,编译器采用就近访问原则访问,
如希望访问匿名结构体的字段和方法,可以通过匿名结构体名来区分
*/

type primaryStudent struct{
    student
    age int
}



func ExtendDemo2()  {

primary := primaryStudent{
    student : student{
        name : "小龙",
        age : 9,
        score : 50,
    },
    age :13,
}
primary.student.showInfor()
primary.showInfor()
}

4、结构体嵌入两个(或多个)匿名结构体,如两个匿名结构体有相同的字段和方法(同时结构体本身没有同名的字段和方法),在访问时,就必须明确指定匿名结构体名字,否则编译报错。【案例演示】

/*
    结构体嵌入两个(或多个)匿名结构体,如两个匿名结构体有相同的字段和方法(同时结构体本身没有同名的字段和方法),
    在访问时,就必须明确指定匿名结构体名字,否则编译报错。
    */

    type person struct {
        name string
        age int
        score float64
    }
    type user struct {
        person
        student
        score float64
    }
    // 如嵌入的匿名结构体有相同的字段名或者方法名,则在访问时,需要通过匿名结构体类型名来区分。
func ExtendDemo3()  {
    var root user
    // root.age = 23
    root.person.age = 23
    root.score = 23
    root.person.score = 23
    root.student.score = 23
}

5、如果一个struct嵌套了一个有名结构体,这种模式就是组合,如果是组合关系,那么在访问组合的结构体的字段或方法时,必须带上结构体的名字。【案例参考4】

6、嵌套匿名结构体后,也可以在创建结构体变量(实例)时,直接指定各个匿名结构体字段的值。

六、多重继承

1、多重继承说明
如一个struct嵌套了多个匿名结构体,那么该结构体可以直接访问嵌套的匿名结构体的字段和方法,从而实现了多重继承。
2、案例演示
通过一个案例来说明多重继承使用。

type Good struct{
    Name string
    Price float64
}
type Band struct{
    Name string
    Address string
}

type Test struct{
    Band
    Good
}
func ExtendDemo5()  {
    var t Test
    t.Band.Name = "zsff"
    t.Good.Name = "qrqf"
}

3、多重继承细节说明
1) 如嵌入的匿名结构体有相同的字段名或者方法名,则在访问时,需要通过匿名结构体类型名来区分。
2) 为了保证代码的简洁性,建议大家尽量不使用多重继承

猜你喜欢

转载自blog.csdn.net/TDCQZD/article/details/81712341