原文链接 http://www.limerence2017.com/2019/09/11/golang12/

golang支持面向对象的设计,一般支持面向对象的语言都会有class的设计,但是golang没有class关键字,只有struct结构体。通过结构体达到类的效果,这叫做大成若缺,其用不弊。

struct简介

在使用struct之前,先介绍golang的一个特性,golang允许用户将类型A定义为另一种类型B,并为类型B添加方法。

1234
type Integer int func (a Integer) Less (b Integer) bool{ return a < b}

我们将int定义为一种新的类型Integer,Integer就和int不是一个类型了,这和C++不一样。然后为Integer添加了方法Less,所有Integer对象都可以使用Less方法。类似于C++的成员函数。下面我们使用一下

12345
func main() { var varint1 Integer = 100 var varint2 Integer = 200 fmt.Println(varint1.Less(varint2))}

定义了两个变量varint1和varint2,调用了varint1的Less方法,输出true
下面介绍struct的基本定义

12345
//构造函数和初始化type Rect struct{ x,y float64 width, height float64}

定义了一个结构体Rect,Rect包含四个成员,x,y为float64类型,width, height为float64类型。
下面为Rect定义方法,计算矩形面积

123
func (r* Rect) Area() float64{ return r.width* r.height}

golang结构体没有public,private等字段,是通过成员的大小写区分权限的。大写的结构体成员,别的包可以访问,小写的成员不可被别的包访问。
Rect的成员都为小写,所以别的包无法访问,但是可以通过定义大写的方法,提供给别的包访问

12345678910111213141516171819
func (r *Rect) GetX() float64 { return r.x}

func (r *Rect) GetY() float64 { return r.y}

func (r *Rect) Area() float64 { return r.width * r.height}

func (r *Rect) GetWidth() float64 { return r.width}

func (r *Rect) GetHeight() float64 { return r.height}

这样其他的包就可以通过Rect的方法访问Rect内部变量值了。

结构体方法和函数的区别

结构体方法就好比是C++的成员函数,是类对象调用的方法。函数和结构体对象无关,可以自由编写。
二者定义也有区别

1234567
func (this* 结构体类型) 方法名(方法参数列表) 方法返回值{ //方法内部实现}

func 函数名(函数参数列表) 函数返回值{ //函数内部实现}

golang的精髓是组合

123456789
type Inner struct { Name string Num int}

type Wrappers struct { inner Inner Name string}

Wrappers 包含了Inner结构体,golang中叫做组合。下面写代码打印信息,我们先为Wrappers添加方法

12345
func (wp *Wrappers) PrintInfo() { fmt.Println(wp.Name) fmt.Println(wp.inner.Name) fmt.Println(wp.inner.Num)}

定义变量调用方法

1234
func main() { wp := &Wrappers{Name: "wrapper", inner: Inner{Name: "inner", Num: 100}} wp.PrintInfo()}

打印结果如下

123
wrapperinner100

组合后,打印内部成员inner的Name需要显示指定wp.inner.Name,因为默认打印wp.Name是Wrappers的。

匿名组合实现继承(派生)

12345678910111213141516171819202122
//匿名组合和派生type Base struct { Name string}

func (base *Base) Foo() { fmt.Println("this is Base Foo")}

func (base *Base) Bar() { fmt.Println("this is Base Bar")}

type Foo struct { //匿名组合 Base}

func (foo *Foo) Foo() { foo.Base.Foo() fmt.Println("this is Foo Foo")}

Foo内部组合了Base,但是并没有显示指定成员名,Foo内部只写了Base类型,这叫做匿名组合,
匿名组合会在Foo内部自动生成Base同名的成员变量Base,golang根据匿名组合,会认为Foo继承自Base,
从而Foo拥有Base的方法和成员。下面写代码看看效果

1234567891011
func main() { foo := &Foo{} //Foo继承Base,所以拥有Name属性 foo.Name = "foobase" //Foo 重写(覆盖)了Base的Foo foo.Foo() //Foo继承了Base的Bar函数 foo.Bar() //显示调用基类Base的Foo foo.Base.Foo()}

由于Foo继承Base后重写了Foo方法,所以想要调用Base的Foo方法,需要显示调用。

匿名指针组合

匿名组合如果是指针类型,在子类对象定义时需要显示初始化基类指针,否则会出问题。
先定义匿名组合结构体

12345678910
//匿名指针组合type DerivePoint struct { *Base}

func (derivep *DerivePoint) Foo() bool { fmt.Println("this is DerivePoint Foo") fmt.Println("inherit base ,name is ", derivep.Name) return true}

定义了DerivePoint类,和方法Foo,在Foo内部打印了derivep的Name,该Name继承自*Base
下面调用

12
dr := &DerivePoint{Base: &Base{Name: "base"}}dr.Foo()

输出如下

12
this is DerivePoint Fooinherit base ,name is  base

可见输出了Name值。

匿名组合造成命名冲突

123456
//重复定义,因为匿名组合默认用类型做变量名type MyJob struct { *Logger Name string *log.Logger // duplicate field Logger}

MyJob匿名组合了Logger类和log.Logger类,由于匿名组合默认用类型做变量名,所以编译器会认为定义了两个Logger名的成员,
从而报错,所以匿名组合一定要注意这一点。

多重继承

golang 支持多重继承,实现多重继承只需要多个匿名组合即可。

golang结构体介绍完毕,关注我的公众号领取学习资料

转载于:https://www.cnblogs.com/secondtonone1/p/11507550.html

golang(07) 结构体介绍相关推荐

  1. Golang 入门 : 结构体(struct)

    Go 通过类型别名(alias types)和结构体的形式支持用户自定义类型,或者叫定制类型.试图表示一个现实世界中的实体. 结构体由一系列命名的元素组成,这些元素又被称为字段,每个字段都有一个名称和 ...

  2. golang修改结构体中的切片值

    golang修改结构体中的切片值,直接传结构体地址就可以 package mainimport "fmt"type rspInfo struct {KeyWords string ...

  3. golang判断结构体为空_如何在Golang中检查结构是否为空?

    golang判断结构体为空 The size of an empty structure is zero in Golang. Here, empty structure means, there i ...

  4. golang获取结构体中的tag_26. Go 语言中结构体的 Tag 用法

    大家好,我是明哥. 由于某些不可抗力,之前该专栏的所有内容都被删除了.因此之后的一段时间内,我会重新发布这些文章,先给已经看过的关注者提个醒. 本文原文:http://golang.iswbm.com ...

  5. Golang笔记——结构体

    结构体 看一个问题 使用现有技术解决 单独的定义变量解决 代码演示: 使用数组解决 现有技术解决的缺点分析 使用变量或者数组来解决养猫的问题,不利于数据的管理和维护.因为名字,年龄,颜色都是 属于一只 ...

  6. Zookeeper C API 基本常量和结构体介绍

    Zookeeper 监视(Watches) 简介 Zookeeper C API 的声明和描述在 include/zookeeper.h 中可以找到,另外大部分的 Zookeeper C API 常量 ...

  7. CMFCPropertySheet的使用及PROPSHEETHEADER结构体介绍

    Visual Studio 2008 SP1自带的示例里面,有个工程为PropSheetDemo,此示例介绍了CMFCPropertySheet属性表的使用,截图如下: 下面以VS2008SP1为测试 ...

  8. golang中结构体转成xml格式

    本文主要介绍结构体与xml格式的字符串进行相互转换,Go自带xml包,所以进行格式转换非常的方便. 一.结构体转成xml格式 1.转成不需要排版的xml格式字符串,可直接使用Marshal()方法 f ...

  9. P-Link ARM Cortex-M脱机编程器开源前的一些准备工作----第四章 几个重要的结构体介绍

    在第二章有提到,SPI Flash预留了2MB来存储目标单片机的固件以及配置信息的,那么相对应的SPI Flash前面会有一个区域用来存储这些信息. T-FLASH_HEAD_INFO结构体描述: t ...

最新文章

  1. 【青少年编程竞赛交流】02月份微信图文索引
  2. 【转载】python3安装scrapy之windows32位爬坑
  3. 【行业趋势】国内这10个AI研究院,你想好去哪个了吗?
  4. Vtk读取并显示保存图像
  5. Asp.Net Core中利用Seq组件展示结构化日志功能
  6. docker安装配置gitlab详细过程
  7. (pytorch-深度学习系列)CNN中的池化层-学习笔记
  8. 视频时代的大数据:问题、挑战与解决方案
  9. Spring框架学习笔记03:初探Spring——利用注解配置类取代Spring配置文件
  10. 以下哪些组件是Oracle,Oracle考试题1参考
  11. 一个rsync自动备份并发信通知的shell脚本
  12. 使用shopnc发送qq邮件遇到的坑
  13. 使用pandas的话,如何直接删除这个表格里面X值是负数的行?
  14. 人工智能是什么,机器学习就是人工智能吗?
  15. 区块链广告平台--【AdRealm】
  16. mysql中双引号和单引号有什么区别
  17. 手写迷你版HashMap
  18. 京东员工出版的计算机书籍,【京东工资】业务员待遇-看准网
  19. 魔兽争霸3冰封王座不能全屏
  20. Oracle中declare如何使用

热门文章

  1. 问题:什么是变量?变量有什么用?
  2. c语言常量和变量有什么区别?
  3. 选修课:唐宋词鉴赏最终作业
  4. 王庆帅(Arthur Wang)
  5. dbproxy选主原理
  6. 2016 驾照考试 科目一 要点
  7. 基本类型和包装类对象使用 == 和 equals进行比较的结果?
  8. 制作抓取APP崩溃和无响应日志的小工具
  9. wps如何输入连续的长破折号
  10. SSD算法原理介绍,包含算法结构、Loss计算、默认框计算几个方面