Go语言中的Oop面向对象

Go In OOp

  • [一、 Go是面向对象的吗?](#一、 Go是面向对象的吗?)
  • [二、Structs Instead of Classes 结构体 - OOP in Go](#二、Structs Instead of Classes 结构体 - OOP in Go)
  • [三、 Composition Instead of Inheritance 组合嵌套 - OOP in Go](#三、 Composition Instead of Inheritance 组合嵌套 - OOP in Go)
    • [1.Composition by embedding structs](#1.Composition by embedding structs)
    • [2. Embedding slice of structs](#2. Embedding slice of structs)
  • [四、Polymorphism 多态 - OOP in Go](#四、Polymorphism 多态 - OOP in Go)
    • [1. Polymorphism using an interface](#1. Polymorphism using an interface)
    • [2. Adding a new income stream to the above program](#2. Adding a new income stream to the above program)

一、 Go是面向对象的吗?

Go is not a pure object oriented programming language. This excerpt taken from Go's FAQs answers the question of whether Go is Object Oriented.

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)
In the upcoming tutorials, we will discuss how object oriented programming concepts can be implemented using Go. Some of them are quite different in implementation compared to other object oriented languages such as Java.
Go不是一种纯粹的面向对象编程语言。这段摘自Go的faq,回答了Go是否是面向对象的问题。

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

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

二、Structs Instead of Classes 结构体 - OOP in Go

go 复制代码
        // 目录结构

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


        // main.go

        package main

        import (
            "oop/employee"
        )

        func main() {
            e := employee.Employee{FirstName: "Mei", LastName: "Jin", TotalLeaves: 666, LeavesTaken: 555}
            e.LeavesRemaining()

            var c employee.Employee
            c.LeavesRemaining()

            d := employee.New("Liang", "xiaoxiao", 888, 777)
            d.LeavesRemaining()
        }


        // 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))
        }



        // 运行结果
        // Mei Jin has 111 leaves remaining
        // has 0 leaves remaining
        // Liang xiaoxiao has 111 leaves remaining

三、 Composition Instead of Inheritance 组合嵌套 - OOP in Go

1.Composition by embedding structs

go 复制代码
        package main

        import (  
            "fmt"
        )

        type author struct {  
            firstName string
            lastName  string
            bio       string
        }

        func (a author) fullName() string {  
            return fmt.Sprintf("%s %s", a.firstName, a.lastName)
        }

        type blogPost struct {  
            title   string
            content string
            author
        }

        func (b blogPost) details() {  
            fmt.Println("Title: ", b.title)
            fmt.Println("Content: ", b.content)
            fmt.Println("Author: ", b.fullName())
            fmt.Println("Bio: ", b.bio)
        }

        func main() {  
            author1 := author{
                "MeiJin",
                "Liang",
                "Golang Enthusiast",
            }
            blogPost1 := blogPost{
                "Inheritance in Go",
                "Go supports composition instead of inheritance",
                author1,
            }
            blogPost1.details()
        }


        // Title: Inheritance in GO
        // Content: GO supports composition instead of inheritance
        // Author: MeiJin Liang
        // Bio: Golang Enthusiast

2. Embedding slice of structs

go 复制代码
        package main

        import "fmt"

        type Author struct {
            firstName string
            lastName  string
            bio       string
        }

        func (a Author) fullName() string {
            return fmt.Sprintf("%s %s", a.firstName, a.lastName)
        }

        type BlogPost struct {
            title   string
            content string
            Author
        }

        func (p BlogPost) details() {
            fmt.Println("Title:", p.title)
            fmt.Println("Content:", p.content)
            fmt.Println("Author:", p.fullName()) // 注意调用的是blogpost里author的fillName方法
            fmt.Println("Bio:", p.bio)
        }

        type WebSite struct {
            BlogPosts []BlogPost
        }

        func (w WebSite) contents() {
            fmt.Println("Contents of Website\n")
            for _, v := range w.BlogPosts {
                v.details()
                fmt.Println()
            }
        }

        func main() {
            author := Author{
                "MeiJin",
                "Liang",
                "Golang Enthusiast",
            }
            blogpost1 := BlogPost{
                "Inheritance in GO",
                "GO supports composition instead of inheritance",
                author,
            }
            blogPost2 := BlogPost{
                "Struct instead of Classes in Go",
                "Go does not support classes but methods can be added to structs",
                author,
            }
            blogPost3 := BlogPost{
                "Concurrency",
                "Go is a concurrent language and not a parallel one",
                author,
            }

            w := WebSite{
                BlogPosts: []BlogPost{blogpost1, blogPost2, blogPost3},
            }
            w.contents()
        }

        // Contents of Website

        // Title: Inheritance in GO
        // Content: GO supports composition instead of inheritance
        // Author: MeiJin Liang
        // Bio: Golang Enthusiast

        // Title: Struct instead of Classes in Go
        // Content: Go does not support classes but methods can be added to structs
        // Author: MeiJin Liang
        // Bio: Golang Enthusiast

        // Title: Concurrency
        // Content: Go is a concurrent language and not a parallel one
        // Author: MeiJin Liang
        // Bio: Golang Enthusiast

四、Polymorphism 多态 - OOP in Go

1. Polymorphism using an interface

go 复制代码
        package main

        import "fmt"

        type Income interface {
            calculate() int
            source() string
        }

        type FixedBilling struct {
            projectName  string
            biddedAmount int
        }

        type TimeAndMaterial struct {
            projectName string
            noOfHours   int
            hourlyRate  int
        }

        func (fb FixedBilling) calculate() int {
            return fb.biddedAmount
        }

        func (fb FixedBilling) source() string {
            return fb.projectName
        }

        func (tm TimeAndMaterial) calculate() int {
            return tm.noOfHours * tm.hourlyRate
        }

        func (tm TimeAndMaterial) source() string {
            return tm.projectName
        }

        func calculateNetIncome(ic []Income) {		// 设置一个变量 每次循环更新一次 最后为结果
            var netincome int = 0
            for _, income := range ic {
                fmt.Printf("Income From %s = $%d\n", income.source(), income.calculate())
                netincome += income.calculate()
            }
            fmt.Printf("Net income of organization = $%d", netincome)
        }

        func main() {
            project1 := FixedBilling{projectName: "Project 1", biddedAmount: 5000}
            project2 := FixedBilling{projectName: "Project 2", biddedAmount: 10000}
            project3 := TimeAndMaterial{projectName: "Project 3", noOfHours: 160, hourlyRate: 25}
            incomeStreams := []Income{project1, project2, project3}
            calculateNetIncome(incomeStreams)
        }


        // Income From Project 1 = $5000
        // Income From Project 2 = $10000
        // Income From Project 3 = $4000
        // Net income of organization = $19000

2. Adding a new income stream to the above program

go 复制代码
        package main

        import "fmt"

        type Income interface {
            calculate() int
            source() string
        }

        type FixedBilling struct {
            projectName  string
            biddedAmount int
        }

        type TimeAndMaterial struct {
            projectName string
            noOfHours   int
            hourlyRate  int
        }

        type Advertisement struct {
            adName     string
            CPC        int
            noOfClicks int
        }

        func (fb FixedBilling) calculate() int {
            return fb.biddedAmount
        }

        func (fb FixedBilling) source() string {
            return fb.projectName
        }

        func (tm TimeAndMaterial) calculate() int {
            return tm.noOfHours * tm.hourlyRate
        }

        func (tm TimeAndMaterial) source() string {
            return tm.projectName
        }

        func (a Advertisement) calculate() int {
            return a.CPC * a.noOfClicks
        }

        func (a Advertisement) source() string {
            return a.adName
        }

        func calculateNetIncome(ic []Income) {
            var netincome int = 0
            for _, income := range ic {
                fmt.Printf("Income From %s = $%d\n", income.source(), income.calculate())
                netincome += income.calculate()
            }
            fmt.Printf("Net income of organization = $%d", netincome)
        }

        func main() {
            project1 := FixedBilling{projectName: "Project 1", biddedAmount: 5000}
            project2 := FixedBilling{projectName: "Project 2", biddedAmount: 10000}
            project3 := TimeAndMaterial{projectName: "Project 3", noOfHours: 160, hourlyRate: 25}
            bannerAd := Advertisement{adName: "Banner Ad", CPC: 2, noOfClicks: 500}
            popupAd := Advertisement{adName: "Popup Ad", CPC: 5, noOfClicks: 750}
            incomeStreams := []Income{project1, project2, project3, bannerAd, popupAd}
            calculateNetIncome(incomeStreams)
        }

        // Income From Project 1 = $5000
        // Income From Project 2 = $10000
        // Income From Project 3 = $4000
        // Income From Banner Ad = $1000
        // Income From Popup Ad = $3750
        // Net income of organization = $23750

技术小白记录学习过程,有错误或不解的地方请指出,如果这篇文章对你有所帮助请点点赞收藏+关注谢谢支持 !!!

相关推荐
ZTLJQ3 小时前
序列化的艺术:Python JSON处理完全解析
开发语言·python·json
2401_891482173 小时前
多平台UI框架C++开发
开发语言·c++·算法
H5css�海秀3 小时前
今天是自学大模型的第一天(sanjose)
后端·python·node.js·php
SuniaWang3 小时前
《Spring AI + 大模型全栈实战》学习手册系列 · 专题六:《Vue3 前端开发实战:打造企业级 RAG 问答界面》
java·前端·人工智能·spring boot·后端·spring·架构
韩立学长3 小时前
Springboot校园跑腿业务系统0b7amk02(程序、源码、数据库、调试部署方案及开发环境)系统界面展示及获取方式置于文档末尾,可供参考。
数据库·spring boot·后端
sheji34163 小时前
【开题答辩全过程】以 基于springboot的扶贫系统为例,包含答辩的问题和答案
java·spring boot·后端
88号技师3 小时前
2026年3月中科院一区SCI-贝塞尔曲线优化算法Bezier curve-based optimization-附Matlab免费代码
开发语言·算法·matlab·优化算法
t198751283 小时前
三维点云最小二乘拟合MATLAB程序
开发语言·算法·matlab
m0_726965984 小时前
面面面,面面(1)
java·开发语言
2401_831920744 小时前
分布式系统安全通信
开发语言·c++·算法