zoukankan      html  css  js  c++  java
  • go结构体继承组合和匿名字段

    1、结构体方法

    go不是纯粹的面向对象的,在go里面函数是一等公民,但是go也有结构体实现类似java一样类的功能来提供抽象。结构体的方法分为值方法指针方法,前者在方法中做的改变不会改变调用的实例对象,后者则会改变,同样不管是值类型还是指针类型都是可以被调用的,因为go结构体底层会自动转化

    比如下面是正常的调用

    type Stu struct {
    	name string
    }
    func (this Stu) SayName()  {
    	log.Println(this.name)
    }
    
    s:=Stu{"Biningo"}
    s.SayName()
    

    如果再定义一个方法

    func (this *Stu) ChangeName(name string)  {
    	this.name = name
    }
    

    因为要改变,所以定义了一个指针类型方法,但是如下调用还是可以的

    s:=Stu{"Biningo"}
    s.ChangeName("xxx")  // 会改变
    
    s2:=&Stu{"Biningo"}
    s2.ChangeName("xxxx")  //会改变
    s2.SayName() //会默认转化 相当于(*s2).SayName() xxxx
    
    

    注意,go中是不允许方法重载的。同时不管是值类型方法还是指针类型方法名字也不允许一样



    2、匿名属性和继承

    继承

    type Camera struct {
    	name string
    }
    type Phone struct{}
    
    func (p *Phone) Call()  {
    	fmt.Println("打电话")
    }
    func (c *Camera) TakePicture()  {
    	fmt.Println("拍照片")
    }
    
    type CameraPhone struct {
    	Camera
    	Phone
    }
    

    继承只需要结构体内嵌一个要继承的结构体就可以了,这样就可以直接使用父类的方法了

    phone:=new(CameraPhone)
    phone.Call()
    phone.TakePicture()
    

    匿名属性:

    type CameraPhone struct {
    	Camera
    	Phone
    	int
    }
    

    我们加了一个int类型,这时候相当于加了一个名字为int,类型为int的属性,名字和类型名一样

    可以如下使用:

    phone:=new(CameraPhone)
    phone.Call()
    phone.TakePicture()
    phone.int=1001
    

    但是注意,匿名属性同类型只允许一个

    那么我们允不允许继承组合一个借口类型呢?那当然也是可以的

    下面看一种结构体和接口的组合并且实现多态:

    type Clothe interface {
    	SayColor()
    }
    
    type BlueClothe struct {
    	Color string
    }
    
    func (b *BlueClothe) SayColor()  {
    	log.Println("Blue")
    }
    
    type RedClothe struct {
    	Color string
    }
    
    func (b *RedClothe) SayColor()  {
    	log.Println("Blue")
    }
    
    
    
    type Stu struct {
    	Clothe
    	Name string
    }
    
    func main() {
    	blue:=&BlueClothe{Color:"Blue"}
    	var stu Stu
    	stu.Clothe = blue //匿名类型名字就是类型名
    	stu.Name="biningo"
    	stu.SayColor()
    }
    



    3、结构体属性名称冲突

    既然可以随意继承组合,并且可以直接由子类调用,那如果继承多个父类有相同的属性名怎么区分呢?如下:

    type A struct {
    	a,b int
    }
    
    type B struct {
    	a int
    }
    

    上面定义了两个结构体,下面继承这两个结构体,注意这里a属性名字相同

    type C struct {A;B}
    

    如下解决冲突

    c:=C{A{1,1},B{2}}
    fmt.Println(c.A.a,c.B.a) //c.a报错 需要指明是A还是B的a 
    

    还记得匿名字段吧,这里就相当于点出具体属性,调用具体属性的属性

    一般匿名字段的方法是可以直接调用的,匿名字段名调用方法的时候是可以忽略字段名的,相当于是一个缩写形式

    但是如果两个冲突字段深度不一样呢?那就是浅的覆盖深的属性

  • 相关阅读:
    kubernetes资源清单之Deployment
    kubernetes资源配置之ReplicaSets
    kubernetes资源清单之pod
    采用kubeadm部署工具,部署kubernetes1.16.3
    Kubernetes介绍与核心组件
    Linux系统初始化脚本
    Linux awk命令 --三剑客老大
    Linux sed命令 -- 三剑客老二
    Makefile中代码写在同一行和分开几行写有什么区别?
    毕业啦!我要好好学习!!!
  • 原文地址:https://www.cnblogs.com/biningooginind/p/12467384.html
Copyright © 2011-2022 走看看