美文网首页
golang结构体组合与“多态” 2021-08-06

golang结构体组合与“多态” 2021-08-06

作者: 9_SooHyun | 来源:发表于2021-11-21 17:13 被阅读0次

1.对于golang的组合结构体S,调用S的方法f,将从当前结构体出发,按照从外到内,从上到下查找f,第一个找到的f被调用

如:

package main

import "fmt"

// X
type X struct {
    a int
}

func (x X) Print() {
    fmt.Printf("In X, a = %d\n", x.a)
}

func (x X) XPrint() {
    fmt.Printf("call XPrint(). In X, a = %d\n", x.a)
}

// Y
type Y struct {
    X
    b int
}

func (y Y) Print() {
    fmt.Printf("In Y, b = %d\n", y.b)
}


// Z
type Z struct {
    Y
    c int
}

func (z Z) Print() {
    fmt.Printf("In Z, c = %d\n", z.c)
    //显式的完全路径调用内嵌字段的方法
    z.Y.Print()
    z.Y.X.Print()
}

func main() {
    x := X{a: 1}
    y := Y{
        X: x,
        b: 2,
    }
    z := Z{
        Y: y,
        c: 3,
    }
    //从外向内查找,首先找到的是 Z 的 Print() 方法
    z.Print()
    
    //从外向内查找,最后找到的是 x 的 XPrint()方法
    z.XPrint() // ->外层结构体自动获得了内部成员的方法
    z.Y.XPrint()
}
>>>
In Z, c = 3
In Y, b = 2
In X, a = 1
call XPrint(). In X, a = 1
call XPrint(). In X, a = 1

go没有继承只有组合,组合实现了继承的效果

package main
 
import (
    "fmt"
)
 
type Base struct {
    // nothing
}
 
func (b *Base) F1() {
    fmt.Println("Base.F1")
    b.F2()
}

func (b *Base) F2() {
    fmt.Println("Base.F2")
}
 
type Derived struct {
    Base
}
 
func (d *Derived) F2() {
    fmt.Println("Derived.F2")
}
 
func main() {
    d := &Derived{}
    d.F1()   
}
>>>
Base.F1
Base.F2
// 不会打印"Derived.F2"
// Derived结构体自动含有了Base的方法,虽然重写了F2()方法,
// 但因为go没有继承只有组合,不会根据对象的不同来执行不同的F2(),调用的b.F2()仍然是*Base的F2()方法

golang如何实现多态的效果?--使用interface

package main
 
import (
    "fmt"
)

// 首先需要一个接口,起到类似基类的作用
type B interface{
    F1()
    F2()
}

// 表示Base结构体含有一个实现了F1()和F2()的成员
type Base struct {
    B
}

// Base重写了F1,没有重写F2()
// 根据结构体的组合关系,b.F2()到底调用哪个F2,需要从Base结构体出发,从外到内从上到下寻找最近的F2
// 因为Base没有重写F2(), 所以最近的F2就是Base.B.F2()
func (b *Base) F1() {
    fmt.Println("Base.F1")
    b.F2() // will call Base.B.F2()
}

type BaseBase struct {
    Base
}

func (b *BaseBase) F2() {
    fmt.Println("BaseBase.F2")
}
 
type Derived struct {
    BaseBase
}
 
func (d *Derived) F2() {
    fmt.Println("Derived.F2")
}
 
func main() {
    ori_impl_1 := &BaseBase{}
        // 重要!!!
    // ###将ori_impl_1作为最底层的B接口实现,就可以调用ori_impl_1的F2###
    var b B = &BaseBase{Base{B:ori_impl_1}}
    b.F1()
    
    ori_impl_2 := &Derived{}
    // 将ori_impl_2作为最底层的B接口实现
    var d B = &Derived{BaseBase{Base{B:ori_impl_2}}}
    d.F1()  
}
>>>
Base.F1
BaseBase.F2
Base.F1
Derived.F2

核心思想就是,外层实现接口,通过递归嵌套将被实现的接口实例置于内层,从而达到外层定义,内层使用的效果
BaseBase和Derived都是外层结构体,在它们这一层实现了F2()。ori_impl_1以及ori_impl_2都是外层结构体实现的B接口实例,置于内层完成调用

2. 匿名结构体和结构体的递归嵌套

匿名结构体

struct中的字段可以不用给名称,这时称为匿名字段。匿名字段的名称强制和类型相同。例如:

type animal struct {
    name string
    age int
}

type Horse struct{
    int
    animal
    sound string
}

// Horse等价于
type Horse struct{
    int int
    animal animal
    sound string
}

struct递归嵌套

如果struct中嵌套的struct类型是自己的指针类型,可以用来生成链表或二叉树等数据结构

例如,定义一个单链表数据结构

type Node struct {
    Data string
    Next *Node
}

相关文章

  • golang结构体组合与“多态” 2021-08-06

    1.对于golang的组合结构体S,调用S的方法f,将从当前结构体出发,按照从外到内,从上到下查找f,第一个找到的...

  • Swift5 _07_多态原理_初始化

    多态 结构体struct与类class 的区别(1)结构体是值类型、类是引用类型(2)类可以继承,结构体不能继承(...

  • golang-结构体

    结构体就是当做实体类来用但是Go里面没有继承和多态,但是可以用扩展和组合方式

  • Learn Golang In Day 9

    Learn Golang In Day 9 简介 结构体是自定义的数据结构 定义结构体 package main ...

  • Swift笔记<十五>结构体和类的区别

    结构体和类的区别 结构体有逐一构造器,类没有 结构体是值类型,类是引用类型 结构体不是继承(意味着没有多态)

  • golang 结构体

     一个结构体类型可以包含若干个字段,也可以不包含任何字段。空结构体可以关联上一些方法,从而看成是函数的特殊版本。 ...

  • Golang:结构体

    结构体 结构体(struct)是用户自定义的类型,代表若干字段的集合。有时将多个数据看做一个整体要比单独使用这些数...

  • Golang结构体

    C++中结构体(struct)和类(class)的主要区别有: struct没有权限控制字段 struct没有方法...

  • golang结构体

    定义 结构体是由一系列具有相同类型或不同类型的数据构成的数据集合 结构体的定义 结构体定义需要使用 type 和 ...

  • Golang 结构体

    继承

网友评论

      本文标题:golang结构体组合与“多态” 2021-08-06

      本文链接:https://www.haomeiwen.com/subject/gknbvltx.html