- 前言
- Go 与操作系统
- Go 内部机制
- Go 基本数据类型
- 4 组合类型的使用
- 5 数据结构
- 6 Go package 中不为人知的知识
- 7 反射和接口
- 8 Go UNIX 系统编程
- 08.1 关于 UNIX 进程
- 08.2 flag 包
- 8.2 flag 包
- 08.3 io.Reader 和 io.Writer 接口
- 08.4 bufio 包
- 08.5 读取文本文件
- 08.6 从文件中读取所需的数据量
- 08.7 为什么我们使用二进制格式
- 08.8 读取 CSV 文件
- 08.9 写入文件
- 08.10 从磁盘加载和保存数据
- 08.11 再看strings包
- 08.12 关于bytes包
- 08.13 文件权限
- 08.14 处理 Unix 信号
- 08.15 Unix 管道编程
- 08.16 遍历目录树
- 08.17 使用 ePBF
- 08.18 关于 syscall.PtraceRegs
- 08.19 跟踪系统调用
- 08.20 User ID 和 group ID
- 08.21 其他资源
- 08.22 练习
- 08.23 总结
- 9 并发 Goroutines、Channel 和 Pipeline
- 10 Go 并发-进阶讨论
- 11 代码测试、优化及分析
- 12 Go 网络编程基础
- 13 网络编程 - 构建服务器与客户端
07.6 Go 的 OOP 思想
现在应该了解Go语言缺少继承,但它支持组合,并且Go接口提供了一种多态性。所以,尽管Go不是面向对象的编程语言,但它有一些特性可以让您模拟面向对象的编程。
如果您真的想使用面向对象的方法开发应用程序,那么Go语言可能不是您的最佳选择。由于我不是很喜欢Java,我建议看一下C++或Python。当然,Go禁止构建复杂而深入的类型层次结构,也是因为这些深层次结构很难使用和维护!
首先,让我解释这一部分中将使用的两种Go语言技术。第一种技术使用方法将函数与类型关联起来。这意味着,在某种程度上,您可以考虑函数和数据类型构造了一个对象。
使用第二种技术,可以将数据类型嵌入到新的结构类型中,以便创建一种层次结构。
还有第三种技术,即使用Go接口生成两个或多个元素——一个类的多个对象。因为本章前面的章节刚刚进行了论述,本节将不介绍这种技术。这个技术的关键点是Go接口允许您在不同的元素之间定义一个共同的行为(函数方法),这样所有这些不同的元素都可以共享一个对象的特性,因此可以认为这些不同的元素是同一个类的对象。然而,实际的面向对象编程语言的对象和类可以做更多的事情。
前两种技术将在 ooo.go
程序中进行说明,该程序将分四部分介绍。 ooo.go
的第一段包含以下Go代码:
> package main
>
> import (
> "fmt"
> )
>
> type a struct {
> XX int
> YY int
> }
>
> type b struct {
> AA string
> XX int
> }
ooo.go
程序的第二部分如下:
> type c struct {
> A a
> B b
> }
在Go语言中,组合技术允许使用多个 struct
类型创建一个新的结构。在以上代码示例中,数据类型 c```由一个结构体
a的变量和一个结构体
b```的变量组合而成。
以下Go代码是 ooo.go
的第三部分:
> func (A a) A() {
> fmt.Println("Function A() for A")
> }
>
> func (B b) A() {
> fmt.Println("Function A() for B")
> }
此处定义的两个方法可以使用相同的名称( A()
),因为它们具有不同的函数头。第一种方法使用 a```变量,而第二种方法使用
b```变量。此技术允许您在多个类型之间共享相同的函数名。
代码 ooo.go
的最后一部分如下:
> func main() {
> var i c
> i.A.A()
> i.B.A()
> }
与实现抽象类和继承的面向对象编程语言代码相比, ooo.go
中的所有Go代码都非常简单。而且,它对于生成具有结构的类型和元素,以及具有相同方法名的不同数据类型来说是足够的。
执行 ooo.go
程序的输出如下:
$ go run ooo.go Function A() for A Function A() for B
以下代码则说明了组合与继承的差异,结构体 first
对结构体 second
调用 shared()
函数,对其所做的更改一无所知:
> package main
>
> import (
> "fmt"
> )
>
> type first struct{}
>
> func (a first) F() {
> a.shared()
> }
>
> func (a first) shared() {
> fmt.Println("This is shared() from first!")
> }
>
> type second struct {
> first
> }
>
> func (a second) shared() {
> fmt.Println("This is shared() from second!")
> }
>
> func main() {
> first{}.F()
> second{}.shared()
> i := second{}
> j := i.first
> j.F()
> }
通过以上代码可以看到结构体 second
嵌入了结构体 first
,这两个结构体共享一个名为 shared()
的函数。
以上Go代码保存为goCoIn.go并执行,将生成以下输出:
$ go run goCoIn.go This is shared() from first! This is shared() from second! This is shared() from first!
first{}.F()
和 second{}.shared()
的函数调用生成了预期的结果。尽管结构体 second
重新实现了 shared()
函数,对 j.F()
的调用仍然调用了 first.shared()
而不是 second.shared()
函数。在面向对象语言的术语中这样的操作叫做方法重写
。
另外可以将 j.F()
调用可以简写成(i.first).F()
或(second{}.first).F()
,而不需要定义太多的变量。为了更容易理解,上面的调用将这个过程分成三行代码。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论