Go 中的 OOP- 用结构体代替类

这篇具有很好参考价值的文章主要介绍了Go 中的 OOP- 用结构体代替类。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Go是面向对象的吗?

Go 不是一种纯粹的面向对象编程语言。这段摘录自 Go 的常见问题解答,回答了 Go 是否是面向对象的问题。

是也不是。虽然Go有类型和方法,并且允许面向对象的编程风格,但是没有类型层次结构。Go中的“接口”概念提供了一种不同的方法,我们认为这种方法易于使用,并且在某些方面更通用。还有一些方法可以将类型嵌入到其他类型中,以提供类似于子类化(但不完全相同)的东西。此外,Go中的方法比c++或Java中的方法更通用:它们可以为任何类型的数据定义,甚至可以为内置类型(如普通的“未装箱”整数)定义。它们并不局限于结构体(类)。

此外,由于缺乏类型层次结构,Go中的“对象”感觉比c++或Java等语言要轻得多。

在接下来的教程中,我们将讨论如何使用 Go 实现面向对象的编程概念。与其他面向对象语言(例如 Java)相比,其中一些在实现上有很大不同。

使用结构体代替类

Go 不提供类,但它提供结构体。可以在结构上添加方法。这提供了将数据和对数据进行操作的方法捆绑在一起的行为,类似于类。

让我们立即从一个例子开始,以便更好地理解。

我们将在此示例中创建一个自定义包,因为它有助于更好地理解结构如何有效替代类。

在里面创建一个子文件夹~/Documents/并命名oop

让我们初始化一个名为 的 go 模块oop。输入以下命令

go mod init oop  

在里面创建一个子文件夹employee。在employee文件夹内,创建一个名为employee.go

文件夹结构看起来像,

├── Documents
│   └── oop
│       ├── employee
│       │   └── employee.go
│       └── go.mod

请将employee.go的内容替换为以下内容,

package employee

import (  
    "fmt"
)

type Employee struct {  
    FirstName   string
    LastName    string
    TotalLeaves int
    LeavesTaken int
}

func (e Employee) LeavesRemaining() {  
    fmt.Printf("%s %s has %d leaves remaining\n", e.FirstName, e.LastName, (e.TotalLeaves - e.LeavesTaken))
}

在上面的程序中,第 1 行。指定该文件属于该employee包。

在第7 行声明Employee 结构 ,在14行声明一个名为的方法LeavesRemaining。现在我们有一个结构体和一个对结构体进行操作的方法,它们类似于类一样捆绑在一起。

oop文件夹内命名创建main.go

现在文件夹结构看起来像

├── Documents
│   └── oop
│       ├── employee
│       │   └── employee.go
│       ├── go.mod
│       └── main.go

main.go内容如下

package main

import "oop/employee"

func main() {  
    e := employee.Employee {
        FirstName: "Sam",
        LastName: "Adolf",
        TotalLeaves: 30,
        LeavesTaken: 20,
    }
    e.LeavesRemaining()
}

我们在第 3 行导入employee包。从第 12 行调用该结构体的方法LeavesRemaining()

该程序将打印输出,

Sam Adolf has 10 leaves remaining  

New() 函数而不是构造函数

我们上面编写的程序看起来不错,但其中有一个微妙的问题。让我们看看当我们用零值定义员工结构时会发生什么。将 main.go的内容替换为以下代码,

package main

import "oop/employee"

func main() {  
    var e employee.Employee
    e.LeavesRemaining()
}

我们所做的唯一更改是创建零值Employee。该程序将输出,

  has 0 leaves remaining

正如您所看到的,使用 0 值创建的变量Employee是不可用的。它没有有效的名字、姓氏,也没有有效的休假详细信息。

在其他 OOP 语言(如 java)中,这个问题可以通过使用构造函数来解决。可以使用参数化构造函数创建有效的对象。

Go 不支持构造函数。如果类型的零值不可用,则程序员的工作是取消导出该类型以防止从其他包访问,并提供一个名为NewT(parameters)的函数,该函数用所需的值初始化为类型T

Go 中的约定是命名一个创建NewT(parameters)的函数。这将充当构造函数。如果包只定义了一种类型,那么 Go 中的约定是将此函数命名New(parameters)

让我们对我们编写的程序进行更改,以便每次创建员工时都可用。

第一步是取消导出Employee结构并创建一个函数New()来创建新的Employee. 将代码替换employee.go 为以下内容,

package employee

import (  
    "fmt"
)

type employee struct {  
    firstName   string
    lastName    string
    totalLeaves int
    leavesTaken int
}

func New(firstName string, lastName string, totalLeave int, leavesTaken int) employee {  
    e := employee {firstName, lastName, totalLeave, leavesTaken}
    return e
}

func (e employee) LeavesRemaining() {  
    fmt.Printf("%s %s has %d leaves remaining\n", e.firstName, e.lastName, (e.totalLeaves - e.leavesTaken))
}

我们在这里做了一些重要的改变。我们在第 7行将 Employee 结构体的首字母改为小写。那就是我们已经改成type employee struct。通过这样做,我们成功地取消了employee结构的导出并阻止了其他包的访问。最好将未导出结构体的所有字段也设为未导出,除非有特定需要导出它们。由于我们不需要在包employee外的任何地方访问结构体的字段employee,因此我们也取消导出所有字段。

我们在LeavesRemaining()方法中相应地更改了字段名称。

现在,由于employee未导出,因此无法Employee从其他包创建类型的值。因此,我们在第14 行提供了一个导出New函数。它将所需的参数作为输入并返回新创建的员工。

该程序仍然需要进行更改才能使其正常工作,但让我们运行它来了解到目前为止更改的效果。如果运行该程序,它将失败并出现以下编译错误,

# oop
./main.go:6:8: undefined: employee.Employee

这是因为我们的employee包中有一个未导出的employee,文件并且无法从main包中访问它。因此,编译器会抛出一个错误,指出该类型未在main.go 中定义。这正是我们想要的。现在没有其他包能够创建零值employee。我们已成功阻止创建无法使用的员工结构值。现在创建员工的唯一方法是使用该New函数。

main.go的内容替换为以下内容,

package main  

import "oop/employee"

func main() {  
    e := employee.New("Sam", "Adolf", 30, 20)
    e.LeavesRemaining()
}

该文件的唯一更改是第 16 行。 我们通过将所需的参数传递给函数来创建一个新员工New

下面提供了进行所需更改后这两个文件的内容。

employee.go

package employee

import (  
    "fmt"
)

type employee struct {  
    firstName   string
    lastName    string
    totalLeaves int
    leavesTaken int
}

func New(firstName string, lastName string, totalLeave int, leavesTaken int) employee {  
    e := employee {firstName, lastName, totalLeave, leavesTaken}
    return e
}

func (e employee) LeavesRemaining() {  
    fmt.Printf("%s %s has %d leaves remaining\n", e.firstName, e.lastName, (e.totalLeaves - e.leavesTaken))
}

main.go

package main  

import "oop/employee"

func main() {  
    e := employee.New("Sam", "Adolf", 30, 20)
    e.LeavesRemaining()
}

运行该程序将输出,

Sam Adolf has 10 leaves remaining  

因此你可以理解,虽然 Go 不支持类,但是可以有效地使用结构体来代替类,并且New(parameters)可以使用签名方法来代替构造函数。

这就是 Go 中的类和构造函数。请留下您的宝贵意见和反馈。文章来源地址https://www.toymoban.com/news/detail-741451.html

到了这里,关于Go 中的 OOP- 用结构体代替类的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Golang】go编程语言适合哪些项目开发?

    前言 在当今数字化时代,软件开发已成为各行各业的核心需求之一。 而选择适合的编程语言对于项目的成功开发至关重要。 本文将重点探讨Go编程语言适合哪些项目开发,以帮助读者在选择合适的编程语言时做出明智的决策。 Go 编程语言适合哪些项目开发? Go是由Google开发

    2024年02月04日
    浏览(80)
  • Go后端开发 -- 面向对象特征:结构体 && 继承 && 多态 && interface

    type 用来声明数据类型 使用 type 定义结构体 对于结构体对象: 可以先定义后初始化; 也可以直接在{}中初始化 值传参 传递的是结构体的拷贝,原结构体不会发生改变 引用传递 传递的是结构体的指针,原结构体的值会改变 GetName 这个函数前面的 (this Hero) 表明这个函数是绑定

    2024年01月17日
    浏览(45)
  • 《Go语言在微服务中的崛起:为什么Go是下一个后端之星?》

    🌷🍁 博主猫头虎🐅🐾 带您进入 Golang 语言的新世界✨✨🍁 🦄 博客首页 ——🐅🐾猫头虎的博客🎐 🐳 《面试题大全专栏》 🦕 文章图文并茂🦖生动形象🐅简单易学!欢迎大家来踩踩~🌺 🌊 《IDEA开发秘籍专栏》 🐾 学会IDEA常用操作,工作效率翻倍~💐 🌊 《100天精通

    2024年02月09日
    浏览(82)
  • 100天精通Golang(基础入门篇)——第5天: Go语言中的数据类型学习

    🌷 博主 libin9iOak带您 Go to Golang Language.✨ 🦄 个人主页——libin9iOak的博客🎐 🐳 《面试题大全》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺 🌊 《IDEA开发秘籍》学会IDEA常用操作,工作效率翻倍~💐 🪁 希望本文能够给您带来一定的帮助🌸文章粗浅,敬请批

    2024年02月08日
    浏览(46)
  • 【Golang】VsCode下开发Go语言的环境配置(超详细图文详解)

    📓推荐网站(不断完善中):个人博客 📌个人主页:个人主页 👉相关专栏:CSDN专栏、个人专栏 🏝立志赚钱,干活想躺,瞎分享的摸鱼工程师一枚 ​ 话说在前,Go语言的编码方式是 UTF-8 ,理论上你直接使用文本进行编辑也是可以的,当然为了提升我们的开发效率我们还是需

    2024年02月07日
    浏览(84)
  • 【Golang星辰图】数据管理利器:Go编程语言中的数据库和搜索引擎综合指南

    Go编程语言是一种强大、类型安全且高效的编程语言,它在处理数据库和搜索引擎方面有着广泛的应用。本篇文章将详细介绍几个Go编程语言中常用的数据库和全文搜索引擎,包括Go-bleve、Go-pgx、Go-leveldb/leveldb、Go-xorm、Go-mysql-driver和Go-bbolt/bbolt。对于每个工具,我们将介绍其功

    2024年03月26日
    浏览(71)
  • 100天精通Golang(基础入门篇)——第12天:深入解析Go语言中的集合(Map)及常用函数应用

    🌷 博主 libin9iOak带您 Go to Golang Language.✨ 🦄 个人主页——libin9iOak的博客🎐 🐳 《面试题大全》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺 🌊 《IDEA开发秘籍》学会IDEA常用操作,工作效率翻倍~💐 🪁 希望本文能够给您带来一定的帮助🌸文章粗浅,敬请批

    2024年02月12日
    浏览(49)
  • Go语言中的结构体详解

    Golang 中没有“类”的概念,Golang 中的结构体和其他语言中的类有点相似。和其他面向对 象语言中的类相比,Golang 中的结构体具有更高的扩展性和灵活性。 Golang 中的基础数据类型可以表示一些事物的基本属性,但是当我们想表达一个事物的全 部或部分属性时,这时候再用单

    2024年02月15日
    浏览(40)
  • 初识Go语言25-数据结构与算法【堆、Trie树、用go中的list与map实现LRU算法、用go语言中的map和堆实现超时缓存】

      堆是一棵二叉树。大根堆即任意节点的值都大于等于其子节点。反之为小根堆。   用数组来表示堆,下标为 i 的结点的父结点下标为(i-1)/2,其左右子结点分别为 (2i + 1)、(2i + 2)。 构建堆   每当有元素调整下来时,要对以它为父节点的三角形区域进行调整。 插入元素

    2024年02月12日
    浏览(59)
  • Go语言中的结构体:灵活性与可扩展性的重要角色

    结构体是Go语言中重要且灵活的概念之一。结构体的使用使得我们可以定义自己的数据类型,并将不同类型的字段组合在一起,实现更灵活的数据结构。本文旨在深入介绍Go语言中的结构体,揭示其重要性和灵活性,并向读者展示结构体支持的众多特性,展示其强大之处。 在

    2024年02月08日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包