Go 语言入门很简单:Go 如何面向对象

简介: 我们一直学习的是 Go 不支持面向对象,取而代之的是组合的方式。Go 利用接口可以实现类似面对对象的功能,比如多态。虽然 Go 语言并非面向对象的语言,但它还是包含了一些特征可模拟面向对象的编程语言。

我们一直学习的是 Go 不支持面向对象,取而代之的是组合的方式。Go 利用接口可以实现类似面对对象的功能,比如多态。虽然 Go 语言并非面向对象的语言,但它还是包含了一些特征可模拟面向对象的编程语言。


面向对象三大特征

我们知道,面向对象编程语言有三大关键特征:封装继承多态

所谓多态就是指一个类实例的相同方法在不同情形有不同表现形式。多态机制使具有不同内部结构的对象可以共享相同的外部接口。多态其实 Go 已经帮我们实现了。通过利用 Go 接口生成同一类的两个或多个元素对象。这一点在 Go 接口的文章中已经提过。接下来着重关注于其他两个特征。

所谓封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。

所谓继承,是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。通过继承创建的新类称为“子类”或“派生类”,被继承的类称为“基类”、“父类”或“超类”。继承的过程,就是从一般到特殊的过程。要实现继承,可以通过“继承”(Inheritance)和“组合”(Composition)来实现。继承概念的实现方式有二类:实现继承与接口继承


Go 实现封装

Go 如何实现封装。其实只要实现类,类是面向对象编程语言是很关键的概念,类包含成员变量和成员函数。那么 Go 如何模拟类呢?使用某种方法将函数和类型关联,函数和类型构建一个对象。

package main
import (
  "fmt"
)
type ca struct {
  XX int
  YY int
}
type cb struct {
  XX string
  YY int
}
type cc struct {
  A ca
  B cb
}
func (A ca) A() {
  fmt.Println("Function A() for A")
  fmt.Println(A.XX)
}
func (B cb) A() {
  fmt.Println("Function A() for B")
  fmt.Println(B.XX)
}
func main() {
  var ci cc
  ci.A.XX = 2022
  ci.B.XX = "你好,2022"
  ci.A.A()
  ci.B.A()
}

执行上述代码,将得到如下结果。

[Running] go run "/Users/yuzhou_1su/GoProjects/GoOOP/main.go"
Function A() for A
2022
Function A() for B
你好,2022


代码解释,这里我们先通过定义两个结构体 cacb ,然后通过结构体 cccacb 组合起来,这样就类似绑定了两个成员,然后定义两个方法包含相同的名称 A() ,因为它们拥有不同的函数头,第一个方法适合变量 ca , 第二个方法适用于变量 cb

这样我们就通过结构体和同名函数实现了成员变量和成员函数的功能,虽然与面向对象语言相比要简单很多,但是通过这一功能实现了类的概念。


Go 实现继承

Go 如何实现继承。其他面向对象的语言,是使用 extends 关键字来表示继承的,而 go 语言中继承的设计非常简单,不需要额外的关键字。

package main
import "fmt"
type Person struct {
  name string
  age  int
}
type Student struct {
  Person
  id    int
  score int
}
func (person *Person) showInfo() {
  fmt.Printf("My name is %s , age is %d ", person.name, person.age)
}
func (person *Person) setAge(age int) {
  person.age = age
}
func (student *Student) showInfo() {
  fmt.Println("I am a student ...")
}
func (student *Student) read() {
  fmt.Println("read book ...")
}
func main() {
  student := Student{Person{"Etta", 24}, 1001, 100}
  student.showInfo()
  student.setAge(22)
  student.read()
}

运行该代码:

[Running] go run "/Users/yuzhou_1su/GoProjects/GoOOP/v2/main.go"
I am a student ...
read book ...


可以看到,在学生结构体中,我们使用到了Person作为匿名变量,意思就是,Student 继承自 Person。我们除了继承了成员变量和成员方法之外,还可以为学生结构体增加成员方法,重写成员方法。


Go 实现重载

Go 如何实现重载,是通过将类型嵌入新的结构类型中,形成一种层次关系。Go 接口可以在不同元素间定义公共行为,以使这些不同的元素可共享某个对象的特征。

package main
import "fmt"
type father struct{}
func (a father) F() {
  a.shared()
}
func (a father) shared() {
  fmt.Println("This is shared() from father!")
}
type son struct {
  father
}
func (a son) shared() {
  fmt.Println("This is shared() from son!")
}
func main() {
  father{}.F()
  son{}.shared()
  i := son{}
  j := i.father
  j.F()
}

此处代码通过 son 类型嵌入了 father 类型,而这两种类型共享 shared() 函数。运行该代码,得到:

[Running] go run "/Users/yuzhou_1su/GoProjects/GoOOP/v2/main.go"
This is shared() from father!
This is shared() from son!
This is shared() from father!

虽然 father{}.F()son{}.shared() 函数生成了期望的结果,但 j.F() 函数仍然调用了 father.shared() 函数而不是 son.shared() 函数,尽管 son 类型改变了 shared() 函数实现。

总结

面向对象语言的类和对象能实现更多功能。Go 只能通过结构体和接口去实现了类似的效果,但 Go 创建者并不推荐大家以此方式去工作,合理利用组合的概念才是 Go 更合理的开发模式。

相关文章
|
1天前
|
安全 测试技术 数据库连接
使用Go语言进行并发编程
【5月更文挑战第15天】Go语言以其简洁语法和强大的并发原语(goroutines、channels)成为并发编程的理想选择。Goroutines是轻量级线程,由Go运行时管理。Channels作为goroutine间的通信机制,确保安全的数据交换。在编写并发程序时,应遵循如通过通信共享内存、使用`sync`包同步、避免全局变量等最佳实践。理解并发与并行的区别,有效管理goroutine生命周期,并编写测试用例以确保代码的正确性,都是成功进行Go语言并发编程的关键。
|
1天前
|
数据采集 监控 Java
Go语言并发编程:Goroutines和Channels的详细指南
Go语言并发编程:Goroutines和Channels的详细指南
11 3
|
1天前
|
数据采集 人工智能 搜索推荐
快速入门:利用Go语言下载Amazon商品信息的步骤详解
本文探讨了使用Go语言和代理IP技术构建高效Amazon商品信息爬虫的方法。Go语言因其简洁语法、快速编译、并发支持和丰富标准库成为理想的爬虫开发语言。文章介绍了电商网站的发展趋势,如个性化推荐、移动端优化和跨境电商。步骤包括设置代理IP、编写爬虫代码和实现多线程采集。提供的Go代码示例展示了如何配置代理、发送请求及使用goroutine进行多线程采集。注意需根据实际情况调整代理服务和商品URL。
快速入门:利用Go语言下载Amazon商品信息的步骤详解
|
1天前
|
存储 编译器 Go
Go语言学习12-数据的使用
【5月更文挑战第5天】本篇 Huazie 向大家介绍 Go 语言数据的使用,包含赋值语句、常量与变量、可比性与有序性
41 6
Go语言学习12-数据的使用
|
1天前
|
Java Go
一文带你速通go语言指针
Go语言指针入门指南:简述指针用于提升效率,通过地址操作变量。文章作者sharkChili是Java/CSDN专家,维护Java Guide项目。文中介绍指针声明、取值,展示如何通过指针修改变量值及在函数中的应用。通过实例解析如何使用指针优化函数,以实现对原变量的直接修改。作者还邀请读者加入交流群深入探讨,并鼓励关注其公众号“写代码的SharkChili”。
14 0
|
1天前
|
存储 缓存 Java
来聊聊go语言的hashMap
本文介绍了Go语言中的`map`与Java的不同设计思想。作者`sharkChili`是一名Java和Go开发者,同时也是CSDN博客专家及JavaGuide项目的维护者。文章探讨了Go语言`map`的数据结构,包括`count`、`buckets指针`和`bmap`,解释了键值对的存储方式,如何利用内存对齐优化空间使用,并展示了`map`的初始化、插入键值对以及查找数据的源码过程。此外,作者还分享了如何通过汇编查看`map`操作,并鼓励读者深入研究Go的哈希冲突解决和源码。最后,作者提供了一个交流群,供读者讨论相关话题。
17 0
|
1天前
|
Java Go
Go语言学习11-数据初始化
【5月更文挑战第3天】本篇带大家通过内建函数 new 和 make 了解Go语言的数据初始化过程
19 1
Go语言学习11-数据初始化
|
1天前
|
自然语言处理 安全 Java
速通Go语言编译过程
Go语言编译过程详解:从词法分析(生成token)到句法分析(构建语法树),再到语义分析(类型检查、推断、匹配及函数内联)、生成中间码(SSA)和汇编码。最后,通过链接生成可执行文件。作者sharkchili,CSDN Java博客专家,分享技术细节,邀请读者加入交流群。
24 2
|
1天前
|
Java Linux Go
一文带你速通Go语言基础语法
本文是关于Go语言的入门介绍,作者因其简洁高效的特性对Go语言情有独钟。文章首先概述了Go语言的优势,包括快速上手、并发编程简单、设计简洁且功能强大,以及丰富的标准库。接着,文章通过示例展示了如何编写和运行Go代码,包括声明包、导入包和输出语句。此外,还介绍了Go的语法基础,如变量类型(数字、字符串、布尔和复数)、变量赋值、类型转换和默认值。文章还涉及条件分支(if和switch)和循环结构(for)。最后,简要提到了Go函数的定义和多返回值特性,以及一些常见的Go命令。作者计划在后续文章中进一步探讨Go语言的其他方面。
13 0
|
1天前
|
JavaScript 前端开发 Go
Go语言的入门学习
【4月更文挑战第7天】Go语言,通常称为Golang,是由Google设计并开发的一种编程语言,它于2009年公开发布。Go的设计团队主要包括Robert Griesemer、Rob Pike和Ken Thompson,这三位都是计算机科学和软件工程领域的杰出人物。
16 1

热门文章

最新文章

http://www.vxiaotou.com