1.1.1. 一、继承的实现:

在go语言中,继承是通过嵌套匿名结构体实现的。示例如下:

// 父结构体
type Father struct {
    Name string
    age int
}

// 子结构体
type Son struct {
    Father
    grade string // 年级
}

说明:

在子结构体定义时,在内部放一个父机构体即可实现继承。

1.1.2. 二、完整的使用如下:

// 父结构体
type Father struct {
    Name string
    age int
}

// 子结构体
type Son struct {
    Father
    grade string // 年级
}

func main() {
    son := &Son{}
    // 1、通过Father给父结构体的属性赋值
    son.Father.age = 40
    son.Father.Name = "父亲"
    son.grade = "6年级"
    fmt.Println(son) // &{ {父亲 40} 6年级}


    son2 := &Son{}
    // 2、直接给Father的属性赋值
    son2.age = 40
    son2.Name = "son2父亲"
    son2.grade = "3年级"
    fmt.Println(son2) //&{ {son2父亲 40} 3年级}
}

说明:给父机构体的属性赋值,或查询父机构体的属性值。有2种方式:

  1. 通过父结构体的属性赋值。如:son.Father.age = 40。

  2. 直接赋值。如:son2.age = 40。

1.1.3. 三、子结构体访问父结构体属性的访问原则。

关于父结构体、子结构体属性的访问和修改。有下面几个原则:

  1. 结构体可以使用嵌套匿名结构体(父结构体)所有的字段和方法,即:首字母大写或者小写的字段、方法, 都可以使用。
  2. 不通过父结构体,直接给属性赋值时(son2.age = 40)。编译器会先看Son 中有没有 age, 如果有,则直接赋值给Son中的age。
  3. 如果没有就去看 Son 中嵌入的匿名结构体Father 有没有声明 age 字段,如果有就赋值给Father的age,如果没有继续查找Son 中嵌入的其他匿名结构体(多重继承),如果都找不到就报错。
  4. 当结构体和其内部嵌入的匿名结构体有相同的字段或者方法时,编译器采用就近访问原则访问,如希望访问匿名结构体的字段和方法,可以通过匿名结构体名来区分。
  5. 结构体嵌入两个(或多个)匿名结构体,如两个匿名结构体有相同的字段和方法(同时结构体本身没有同名的字段和方法),在访问时,就必须明确指定匿名结构体名字,否则编译报错。
  6. 如果一个 struct 嵌套了一个有名字的结构体,这种模式就是组合,如果是组合关系,那么在访问组合的结构体的字段或方法时,必须带上结构体的名字。

嵌套有名字的结构体(组合模式),赋值时必须指明结构体名字,示例如下:

// 父结构体
type Father struct {
    Name string
    age int
}

// 子结构体
type Son struct {
    fa Father
    grade string // 年级
}

func main() {
    son := &Son{}
    // 嵌套有名字的结构体(组合模式),赋值时必须指明结构体名字
    son.fa.age = 40
    son.fa.Name = "父亲"
    son.grade = "6年级"
    fmt.Println(son) // &{ {父亲 40} 6年级}
}

注意:组合模式就不是继承了。嵌套匿名结构体才是继承。

7、可以在创建子结构体的示例时,直接指定各个匿名结构体(父结构体)字段的值。

// 父结构体
type Father struct {
    Name string
    age int
}

// 子结构体
type Son struct {
    Father
    grade string // 年级
}

func main() {
    // 指定父结构体的属性值
    son := &Son{Father:Father{Name:"父",age:45},grade:"1年级"}

    fmt.Println(son) // &{ {父 45} 1年级}
}

8、嵌套结构体时,可以嵌套指针。效率更高。

// 父结构体
type Father struct {
    Name string
    age int
}

// 子结构体
type Son struct {
    *Father //嵌套指针
    grade string 
}

func main() {
    // 指定父结构体的属性值
    son := &Son{
        Father:&Father{Name:"父",age:45},
        grade:"1年级",
    }
    fmt.Println(son) // &{0xc00005a420 1年级}
    fmt.Println(*son.Father) //{父 45}
}

9、嵌套基本类型。访问的时候直接访问。如:son.float64 = 100。

// 子结构体
type Son struct {
    grade string
    int    // 基本类型嵌套
    float64 // 基本类型嵌套
}

func main() {
    son := &Son{
        grade:"1年级",
        int:6,
    }
    son.float64 = 100
    fmt.Println(son.int) // 6
    fmt.Println(son.float64) // 100
}

嵌套基本类型,实际上字段的名字就是基本类型的名字。如int、float64 。如果嵌入2个相同的类型,就会报错。如下:

type Son struct {
   grade string 
   int // 基本类型嵌套 
   int // 报错 
}

10、多重继承:其实就是子结构体中嵌入多个匿名结构体。(不推荐使用)

// 父1
type Father1 struct {
    Name string
    age int
}
// 父2
type Father2 struct {
    Name string
    age int
}

// 子
type Son struct {
    *Father1
    *Father2
}

results matching ""

    No results matching ""