您当前的位置:首页 > 电脑百科 > 程序开发 > 编程百科

ch15、面向对象编程-行为的定义和实现

时间:2022-07-27 14:55:07  来源:  作者:Return0623260

Is Go an object-oriented language?

Yes and no. Although Go has types and methods and allows an object-oriented style of programming, there is no type hierarchy. The concept of “interface” in Go provides a different approach that we believe is easy to use and in some ways more general. There are also ways to embed types in other types to provide something analogous—but not identical—to subclassing. Moreover, methods in Go are more general than in C++ or Java: they can be defined for any sort of data, even built-in types such as plain, “unboxed” integers. They are not restricted to structs (classes).

Also, the lack of a type hierarchy makes “objects” in Go feel much more lightweight than in languages such as C++ or Java.

Go语言的FQA页面:Frequently Asked Questions (FAQ) - The Go Programming Language?

1、封装数据和行为(方法)

Go语言封装数据:

/*type Name struct {}*/package encapsulationtype Employee struct {  Id   string  Name string  Age  int}

数据的初始化:

package encapsulationimport "testing"type Employee struct {Id   stringName stringAge  int}func TestCreateEmployeeObj(t *testing.T) {// 方法一e := Employee{"0", "Bob", 20}// 方法二e1 := Employee{Name: "Mike", Age: 30}// 方法三,使用new关键字(返回的是指针,使用.访问数据)e2 := new(Employee) // 返回指针e2.Id = "2"e2.Name = "Rose"e2.Age = 22t.Log(e)t.Log(e1)t.Log(e1.Id)t.Log(e2)t.Logf("e is %T", e)t.Logf("e2 is %T", e2)}

封装行为(方法):

package error_test2import ("errors""testing")func GetFibonacci(n int) ([]int, error) {if n < 2 || n > 100 {// 设置error返回10return nil, errors.New("n's should be in [2,100]")}fibList := []int{1, 1}for i := 2; i < n; i++ {fibList = Append(fibList, fibList[i-2]+fibList[i-1])}return fibList, nil}func TestGetFibonacci(t *testing.T) {if v, err := GetFibonacci(-10); err != nil {t.Error(err)} else {t.Log(v)}}
package encapsulationimport ("fmt""testing""unsafe")type Employee struct {Id   stringName stringAge  int}// 第一种定义方式在实例对应方法被调用时,实例的成员会进行值复制func (e Employee) String() string {fmt.Printf("func object Address is %xn", unsafe.Pointer(&e.Name))return fmt.Sprintf("ID:%s-Name:%s-Age:%d", e.Id, e.Name, e.Age)}func TestStructOperations(t *testing.T) {e := Employee{"0", "Bob", 20}e2 := new(Employee) // 返回指针e2.Id = "2"e2.Name = "Rose"e2.Age = 22fmt.Printf("e Address is %xn", unsafe.Pointer(&e.Name))fmt.Printf("e2 Address is %xn", unsafe.Pointer(&e2.Name))t.Log(e.String())t.Log(e2.String())}/*输出的地址不一样,说明是值复制*/

第二种定义方式定义实例对象为指针(go都是值传递,但复制的是指针,指向的是同一块内存)

通常情况下为了避免内存拷贝,使用第二种方式

package encapsulationimport ("fmt""testing""unsafe")type Employee struct {Id   stringName stringAge  int}// 通常情况下为了避免内存拷贝我们使用第二种定义方式(指针,go都是值传递,但复制的是指针,但指向的是同一个)func (e *Employee) String() string {fmt.Printf("func object Address is %xn", unsafe.Pointer(&e.Name))return fmt.Sprintf("ID:%s/Name:%s/Age:%d", e.Id, e.Name, e.Age)}func TestStructOperations(t *testing.T) {e := Employee{"0", "Bob", 20}e2 := new(Employee) // 返回指针e2.Id = "2"e2.Name = "Rose"e2.Age = 22fmt.Printf("e Address is %xn", unsafe.Pointer(&e.Name))fmt.Printf("e2 Address is %xn", unsafe.Pointer(&e2.Name))t.Log(e.String())t.Log(e2.String())}/*输出地址一样,说明指向的是同一块内存*/

思考:第二种方式是否协程或线程安全?即:假如修改了结构体里边的元素值,会污染到其他线程或者协程吗?

2、结构体类型转换

属性名、属性类型、属性个数、排列顺序都是类型组成部分

  • 只有属性名、属性类型、属性个数、排列顺序都相同的结构体类型才能转换(且是强制转换)
package mAInimport "fmt"func main() {type Person1 struct {name stringage  int}type Person2 struct {name stringage  int}type Person3 struct {age  intname string}type Person4 struct {nm  stringage int}type Person5 struct {name stringage  string}type Person6 struct {name   stringage    intgender string}var p1 Person1 = Person1{"lnj", 33}var p2 Person2// 类型名称不一样不能直接赋值(Person1、Person2)//p2 = p1// 虽然类型名称不一样, 但是两个类型中的`属性名称`、`属性类型`、`属性个数`、`排列顺序`都一样,所以可以强制转换p2 = Person2(p1)fmt.Println(p2)// 两个结构体类型中的`属性名称`、`属性类型`、`属性个数`都一样,但是`排列顺序`不一样,所以不能强制转换//var p3 Person3//p3 = Person3(p1)//fmt.Println(p3)// 两个结构体类型中的`属性类型`、`属性个数`、`排列顺序`都一样,但是`属性名称`不一样,所以不能强制转换//var p4 Person4//p4 = Person4(p1)//fmt.Println(p4)// 两个结构体类型中的`属性名称`、`属性个数`、`排列顺序`都一样,但是`属性类型`不一样,所以不能强制转换//var p5 Person5//p5 = Person5(p1)//fmt.Println(p5)// 两个结构体类型中的`属性名称`、`属性类型`、`排列顺序`都一样,但是`属性个数`不一样,所以不能强制转换//var p6 Person6//p6 = Person6(p1)//fmt.Println(p6)}

3、匿名属性

  • 没有指定属性名称,只有属性的类型, 我们称之为匿名属性
  • 任何有命名的数据类型都可以作为匿名属性(int、float、bool、string、struct等)
package mainimport "fmt"func main() {type Person struct {intfloat32boolstring}// 不指定名称初始化per1 := Person{3, 3.14, false, "lnj"}fmt.Println(per1)// 可以把数据类型作为名字显示初始化per2 := Person{int:     3,float32: 3.14,bool:    true,string:  "lnj",}fmt.Println(per2)// 可以把数据类型当做属性名称操作结构体per2.int = 666fmt.Println(per2.int) // 666}
  • Go语言中最常见的匿名属性是用结构体类型作为匿名属性
package mainimport "fmt"func main() {type Person struct {name stringage  int}type Student struct {Person // 匿名属性class  string}stu := Student{Person{"lnj", 33},"学前一班",}fmt.Println(stu) // {{lnj 33} 学前一班}}
  • 如果结构体作为匿名属性, 想访问匿名属性的属性有两种方式
package mainimport "fmt"func main() {type Person struct {name stringage  int}type Student struct {Person // 匿名属性class  string}stu := Student{Person{"lnj", 33},"学前一班",}fmt.Println(stu) // {{lnj 33} 学前一班}// 方式一: 先找到匿名属性,再访问匿名属性中的属性stu.Person.name = "zs"fmt.Println(stu) // {{zs 33} 学前一班}// 方式二: 直接访问匿名属性中的属性// 系统会先查找当前结构体有没有名称叫做name的属性// 如果没有会继续查找匿名属性中有没有名称叫做name的属性stu.name = "ww"fmt.Println(stu) // {{ww 33} 学前一班}}
  • 注意点: 如果多个匿名属性的属性名称相同,那么不能通过方式二操作,只能通过方式一
package mainimport "fmt"func main() {type Person struct {name stringage  int}type Class struct {name stringtime string}type Student struct {Person // 匿名属性Class  // 匿名属性}stu := Student{Person{"lnj", 33},Class{"学前一班", "2020-12-12"},}fmt.Println(stu) // {{lnj 33} {学前一班 2020-12-12}}// 编译报错, 系统搞不清楚要找哪个name//stu.name = "zs"stu.Person.name = "zs"stu.Class.name = "小学一年级"fmt.Println(stu) // {{zs 33} {小学一年级 2020-12-12}}}
  • 注意点: 只有匿名结构体才支持向上查找
package mainimport "fmt"func main() {type Person struct {name string}type Student struct {per Personage int}var stu Student = Student{Person{"lnj"}, 18}//fmt.Println(stu.name) // 报错fmt.Println(stu.per.name) // 必须通过属性进一步查找fmt.Println(stu.age)}
  • 注意点: 如果匿名属性是一个结构体类型, 那么这个结构体类型不能是自己
package mainfunc main() {type Person struct {Person // 错误name   string}type Student struct {*Student // 正确, 链表age      int}    var stu Student = Student{age: 32}var stu2 Student = Student{&stu, 18}fmt.Println(stu)fmt.Println(stu2)}


Tags:   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
凌晨3点北京鬼市,天亮就消失,2大规矩:看货不问价,照货不照人
顾名思义,鬼市开市的时间节点在天明之前,至于起点有的是三更,有的是五更,并无一等。其实鬼市各地都有,只不过北京的鬼市更出名,就连老北京人也觉得这里阴森森的,却又很向往想去探险...【详细内容】
2024-04-19  Search:   点击:(3)  评论:(0)  加入收藏
老美怂了?美国众议院计划给予字节跳动额外180天出售TikTok
据外媒报道,迫使字节跳动剥离TikTok的新众议院法案将包括一项条款,赋予总统允许公司额外180天时间完成出售的自由裁量权。该法案已于3月13日获得众议院投票通过,预计将在周六放...【详细内容】
2024-04-19  Search:   点击:(4)  评论:(0)  加入收藏
Meta AI 全球市场扩张,并上线网页版 meta.ai
IT之家 4 月 19 日消息,Meta 公司近日宣布 Llama 3 大语言模型之外,扩展 Meta AI 服务到美国之外的 13 个国家和地区,还宣布上线专门的聊天网站:meta.ai。Meta 公司在新闻稿中表...【详细内容】
2024-04-19  Search:   点击:(2)  评论:(0)  加入收藏
重磅!Meta推出开源大模型Llama 3,性能直逼GPT-4
每经编辑:杜宇当地时间4月18日,AI 领域迎来重磅消息,Meta正式发布了人们等待已久的开源大模型Llama 3。与此同时,Meta首席执行官扎克伯格宣布:基于最新的Llama 3模型,Meta的AI助手...【详细内容】
2024-04-19  Search:   点击:(4)  评论:(0)  加入收藏
多地将禁止超标车上路,还可以选择骑行电摩,交警告诉你上牌流程
超标电动车由于不符合电动车的安全性能标准,存在着安全隐患,所以在过渡期结束以后,这种车辆将禁止上路行驶,接下来有多地将禁止超标电动车上路。广大车主除了选择电动自行车以外...【详细内容】
2024-04-19  Search:   点击:(3)  评论:(0)  加入收藏
喝完一瓶啤酒,多久才能开车?
首先,需要明确的是,酒驾是极其危险的行为,不仅危及自身安全,还可能威胁到他人生命。根据交通法规,当驾驶人血液中的酒精含量达到或超过20mg/100ml时,即被认定为酒驾,而超过80mg/100...【详细内容】
2024-04-19  Search:   点击:(2)  评论:(0)  加入收藏
古代富人都喜欢“扬州瘦马”,什么是“扬州瘦马”?说出来别不信
扬州的繁荣也催生了一些不道德的商机,其中之一就是“扬州瘦马”。这与其说是一个关于马的故事,不如说是一个关于封建社会对女性的摧残的故事。在中国古代,妇女地位低下,一些父母...【详细内容】
2024-04-19  Search:   点击:(4)  评论:(0)  加入收藏
夫妻一方可查询配偶财产状况,为何多地先后立法?
专家认为,这有助于保障妇女对婚姻财产的知情权。不过近年来实践发现,即便有地方出台类似规定,在现实的执行中仍会遭遇一些阻力,尤其是在查询房产和银行存款方面文|《财经》记者...【详细内容】
2024-04-19  Search:   点击:(3)  评论:(0)  加入收藏
“货币战争”开打?五大央行集体出动!
作者:暴哥来源:暴财经pro(ID:icaijing123)1997年东南亚金融危机重演?亚洲五大央行出手,绝不能让悲剧重来!1美元掀桌子,亚洲货币遭遇一场全面风暴!在《美元开始收割了!》一文中暴哥说过,...【详细内容】
2024-04-19  Search:   点击:(3)  评论:(0)  加入收藏
电影《变形金刚:起源》首支预告片发布:擎天柱、威震天还是好朋友
快科技4月19日消息,日前,1986年之后首部《变形金刚》动画电影《变形金刚:起源》发布首款预告片,影片暂定9月13日北美上映。该片将时间线拨回赛博坦时期,实现了观众一直以来期待的...【详细内容】
2024-04-19  Search:   点击:(2)  评论:(0)  加入收藏
▌简易百科推荐
Meta如何将缓存一致性提高到99.99999999%
介绍缓存是一种强大的技术,广泛应用于计算机系统的各个方面,从硬件缓存到操作系统、网络浏览器,尤其是后端开发。对于Meta这样的公司来说,缓存尤为重要,因为它有助于减少延迟、扩...【详细内容】
2024-04-15    dbaplus社群  Tags:Meta   点击:(3)  评论:(0)  加入收藏
SELECT COUNT(*) 会造成全表扫描?回去等通知吧
前言SELECT COUNT(*)会不会导致全表扫描引起慢查询呢?SELECT COUNT(*) FROM SomeTable网上有一种说法,针对无 where_clause 的 COUNT(*),MySQL 是有优化的,优化器会选择成本最小...【详细内容】
2024-04-11  dbaplus社群    Tags:SELECT   点击:(3)  评论:(0)  加入收藏
10年架构师感悟:从问题出发,而非技术
这些感悟并非来自于具体的技术实现,而是关于我在架构设计和实施过程中所体会到的一些软性经验和领悟。我希望通过这些分享,能够激发大家对于架构设计和技术实践的思考,帮助大家...【详细内容】
2024-04-11  dbaplus社群    Tags:架构师   点击:(2)  评论:(0)  加入收藏
Netflix 是如何管理 2.38 亿会员的
作者 | Surabhi Diwan译者 | 明知山策划 | TinaNetflix 高级软件工程师 Surabhi Diwan 在 2023 年旧金山 QCon 大会上发表了题为管理 Netflix 的 2.38 亿会员 的演讲。她在...【详细内容】
2024-04-08    InfoQ  Tags:Netflix   点击:(5)  评论:(0)  加入收藏
即将过时的 5 种软件开发技能!
作者 | Eran Yahav编译 | 言征出品 | 51CTO技术栈(微信号:blog51cto) 时至今日,AI编码工具已经进化到足够强大了吗?这未必好回答,但从2023 年 Stack Overflow 上的调查数据来看,44%...【详细内容】
2024-04-03    51CTO  Tags:软件开发   点击:(9)  评论:(0)  加入收藏
跳转链接代码怎么写?
在网页开发中,跳转链接是一项常见的功能。然而,对于非技术人员来说,编写跳转链接代码可能会显得有些困难。不用担心!我们可以借助外链平台来简化操作,即使没有编程经验,也能轻松实...【详细内容】
2024-03-27  蓝色天纪    Tags:跳转链接   点击:(16)  评论:(0)  加入收藏
中台亡了,问题到底出在哪里?
曾几何时,中台一度被当做“变革灵药”,嫁接在“前台作战单元”和“后台资源部门”之间,实现企业各业务线的“打通”和全域业务能力集成,提高开发和服务效率。但在中台如火如荼之...【详细内容】
2024-03-27  dbaplus社群    Tags:中台   点击:(14)  评论:(0)  加入收藏
员工写了个比删库更可怕的Bug!
想必大家都听说过删库跑路吧,我之前一直把它当一个段子来看。可万万没想到,就在昨天,我们公司的某位员工,竟然写了一个比删库更可怕的 Bug!给大家分享一下(不是公开处刑),希望朋友们...【详细内容】
2024-03-26  dbaplus社群    Tags:Bug   点击:(9)  评论:(0)  加入收藏
我们一起聊聊什么是正向代理和反向代理
从字面意思上看,代理就是代替处理的意思,一个对象有能力代替另一个对象处理某一件事。代理,这个词在我们的日常生活中也不陌生,比如在购物、旅游等场景中,我们经常会委托别人代替...【详细内容】
2024-03-26  萤火架构  微信公众号  Tags:正向代理   点击:(15)  评论:(0)  加入收藏
看一遍就理解:IO模型详解
前言大家好,我是程序员田螺。今天我们一起来学习IO模型。在本文开始前呢,先问问大家几个问题哈~什么是IO呢?什么是阻塞非阻塞IO?什么是同步异步IO?什么是IO多路复用?select/epoll...【详细内容】
2024-03-26  捡田螺的小男孩  微信公众号  Tags:IO模型   点击:(10)  评论:(0)  加入收藏
相关文章
    无相关信息
站内最新
站内热门
站内头条