【Golang】Go语言中如何面向对象?

news2024/11/16 1:53:42

在这里插入图片描述

✨✨ 欢迎大家来到景天科技苑✨✨

🎈🎈 养成好习惯,先赞后看哦~🎈🎈

🏆 作者简介:景天科技苑
🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。
🏆《博客》:Python全栈,Golang开发,PyQt5和Tkinter桌面开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi,flask等框架,云原生K8S,linux,shell脚本等实操经验,网站搭建,数据库等分享。

所属的专栏:Go语言开发零基础到高阶实战
景天的主页:景天科技苑

在这里插入图片描述

文章目录

  • Go语言怎样实现面向对象
    • 1. 面向对象的三大特性
      • (1)封装
      • (2)继承
        • Go语言的继承:结构体的嵌套
        • 匿名字段方式继承
        • 聚合方式叫组合,不再是继承了
      • (3)多态
    • 2. 方法
      • (1)Go语言中的方法
      • (2)方法与函数对比总结
      • (3)方法的重写

Go语言怎样实现面向对象

Go语言(Golang)虽然不是一个纯粹的面向对象编程语言,但它通过结构体(Struct)、接口(Interface)等机制,提供了面向对象的编程范式。
在实际的项目开发中,使用面向对象的理念可以显著提高代码的可维护性、可扩展性和可复用性。

1. 面向对象的三大特性

面向对象编程(OOP)的核心思想是将数据和操作数据的行为封装到对象中,通过对象之间的交互来完成程序的功能。OOP具有三大特性:封装、继承、多态。

(1)封装

封装是指将某事物的属性和行为包装到对象中,这个对象只对外公布需要公开的属性和行为,而这个公布也是可以有选择性的。在Go语言中,封装主要通过结构体实现。

(2)继承

生活中的继承:
在这里插入图片描述

兔子和羊属于食草动物类,狮子和豹属于食肉动物类。

食草动物和食肉动物又是属于动物类。

所以继承需要符合的关系是:is-a父类更通用,子类更具体

虽然食草动物和食肉动物都是属于动物,但是两者的属性和行为上有差别,所以子类会具有父类的一般特性也会具有自身的特性

继承就是子类继承父类的特征和行为,使得子类具有父类的属性和方法,使得子类具有父类相同的行为。子类会具有父类的一般特性也会具有自身的特性。

java语言的继承,显示声明class User extends Person{
name
age
}
如此,当修改父类名称或者其中的方法,属性名称后,所有的子类的都得同步去改,比较麻烦

Go语言的继承:结构体的嵌套

Go语言中结构体嵌套,有两种方式
1、模拟继承 is - a
哪个结构体被继承(父类),就将哪个结构体当做一个字段写到 子类结构体里面

   type A struct{
      field
   }
   type B struct{
      A  // 匿名字段  B.A
      field
   }
   // B继承A,B是可以直接访问A的属性的

2、聚合关系 has - a

   type C struct{
      field
   }
   type D struct{
      c C  //聚合关系,不使用匿名字段
      field
   }
   // D是无法直接访问C中的属性的,必须使用D.c.c_field
匿名字段方式继承
package main

import "fmt"

// Person 定义一个父类
type Person struct {
    name string
    age  int
}

// Student 定义一个子类,Student拥有了父类所有的属性,还有自己的特性
type Student struct {
    Person // 父类以匿名字段形式作为子类的属性,实现了继承。
    school string
}

func main() {
    // 1、 创建父类对象
    p1 := Person{name: "jingtian", age: 18}
    fmt.Println(p1)
    fmt.Println(p1.name, p1.age)

    // 2、创建子类
    s1 := Student{Person: Person{name: "小明", age: 3}, school: "景天科技苑"}
    fmt.Println(s1)
    fmt.Println(s1.Person.name, s1.Person.age, s1.school)

    // 3、创建子类
    var s2 Student
    s2.Person.name = "张三"
    s2.Person.age = 3
    s2.school = "北大"
    fmt.Println(s2)

    // 概念:提升字段, 只有匿名字段才可以做到
    // Person 在Student中是一个匿名字段, Person中的属性 name age 就是提升字段
    // 所有的提升字段就可以直接使用了,不需要再通过匿名字段点来获取了

    var s3 Student
    //字段提升,可以直接用子类对象操作父类字段
    s3.name = "李四"
    s3.age = 4
    s3.school = "清华"
    fmt.Println(s3)
    fmt.Println(s3.name, s3.age)

}

在这里插入图片描述

聚合方式叫组合,不再是继承了
package main

import "fmt"

//聚合继承

type Human struct {
    name string
    age  int
}

type Man struct {
    //聚合继承,不再以匿名字段形式将父类写在这,而是命名一个变量名
    Human Human
    phone string
}

func main() {

    //创建子类对象
    man := Man{
        Human: Human{"轩辕氏", 999},
        phone: "19899999999",
    }
    fmt.Println(man)
    //访问父类属性,聚合继承不能使用变量提升。提升字段, 只有匿名字段才可以做到
    //聚合方式继承,访问父类属性需要写全,对象.变量名.父类字段名
    fmt.Println(man.Human.name)

}

在这里插入图片描述

继承就是子类继承父类的特征和行为,使得子类具有父类的属性和方法,使得子类具有父类相同的行为。子类会具有父类的一般特性也会具有自身的特性。

匿名字段 + 提升字段:Go语言中的匿名字段。
当继承多个父类具有相同属性字段的时候,就不能再使用字段提升了,因为此时就不能确定使用的是哪个父类的属性。
此时就要加上父类.属性名

(3)多态

多态需要结合接口实现,由于篇幅限制,下一章接着更新,敬请期待!

2. 方法

(1)Go语言中的方法

Go语言中同时拥有函数和方法。一定要和其他只有方法的语言区分开

类:结构体->属性、方法?

Go语言实现方法

方法:需要指定调用者,约定这个方法属于谁的. 对象.方法()

函数:不需要指定调用者,定义了函数就可以直接函数名()调用

方法:可以理解为函数多了一个调用者
方法定义, func 方法调用者 方法名(){} 方法的定义比函数多了个调用者
定义中,函数与方法就不一样,函数是 func 函数名(参数) 返回值 返回值类型 {}
1、方法可以重名,只需要调用者不同
2、如果调用者相同,则不能重名

package main

import "fmt"

// 方法:可以理解为函数多了一个调用者
// 方法可以重名,不同的对象,调用的结果是不一样的

type Dog struct {
    name string
    age  int
}

// 方法定义,   func 方法调用者  方法名()
// 1、方法可以重名,只需要调用者不同
// 2、如果调用者相同,则不能重名
func (dog Dog) eat() {
    fmt.Println("Dog eating...")
}

func (dog Dog) sleep() {
    fmt.Println("Dog sleep...")
}

// 在Go语言中,fmt.Sprintf函数是一个非常实用的函数,它可以将一个字符串格式化为指定的格式。
// 它的用途非常广泛,可以用来构建复杂的字符串,包括打印日志、生成报错信息等。
// 带有参数和返回值的方法
func (dog Dog) xiaohua(food string) string {
    //返回值字符串格式化
    return fmt.Sprintf("%v吃进了%s, 吐出来骨头", dog.name, food)

}

type Cat struct {
    name string
    age  int
}

func (cat Cat) eat() {
    fmt.Println("Cat eating...")
}
func (cat Cat) sleep() {
    fmt.Println("Cat sleep...")
}

func main() {

    // 创建一个对象
    dog := Dog{
        name: "旺财",
        age:  2,
    }
    fmt.Println(dog)
    // 方法的调用,通过对应的结构体对象来调用
    dog.eat()

    //调用带有参数和返回值的方法
    back := dog.xiaohua("肉")
    fmt.Println(back)

    //不同对象调用同名方法
    cat := Cat{name: "喵喵", age: 1}
    cat.eat()

    //打印查看方法所属类型,类型跟函数一样都是func()
    fmt.Printf("方法所属类型: %T\n", cat.eat)
}

在这里插入图片描述

(2)方法与函数对比总结

方法:

  • 某个类的行为功能,需要指定调用者
  • 一段独立的代码功能,必须要使用调用者来调用
  • 多个类的方法可以重名,单个类不行
  • 方法是某个类的动作

函数:

  • 一段独立的代码功能,可以直接调用

  • 命名完全不能冲突

  • 函数是一个特殊的类型

(3)方法的重写

需要和继承结合

子类可以重写父类的方法 override

子类还可以新增自己的方法

子类可以访问父类中的属性和方法
子类重写父类方法,方法名与父类方法相同,只是调用者改成了子类

package main

import (
    "fmt"
)

// 方法重写,建立在父类和子类结构上的

type Animal struct {
    name string
    age  int
}

// 父类方法
func (animal Animal) eat() {
    fmt.Println(animal.name, " 正在吃....")
}
func (animal Animal) sleep() {
    fmt.Println(animal.name, " 正在sleep....")
}

//父类更通用,子类更具体

// 子类

type Dog2 struct {
    Animal
}

// 子类自己的方法
func (dog Dog2) wang() {
    fmt.Println("wangwangwanwg~~~")
}

type Cat2 struct {
    Animal
    color string // 子类可以定义自己的属性
}

// 子类重写父类的方法 , 子类的方法名和父类同名,即可重写父类的方法
func (cat Cat2) eat() {
    fmt.Println(cat.name, " 正在吃cat....")
}

func main() {
    // 定义一个子类,使用父类方法
    dog := Dog2{Animal{name: "旺财", age: 3}}
    dog.eat()  // 调用父类的方法
    dog.wang() // 调用自己扩展的方法

    cat := Cat2{Animal{name: "煤球", age: 3}, "黑色"}
    cat.eat() // 如果重写了父类的方法就是调用子类自己的方法

    fmt.Println(cat.color) // 调用子类自己的属性

    // 子类可以操作父类的方法,父类可以操作子类的吗?不可以
    // 父类不能调用子类自己的扩展的方法
    a := Animal{name: "大黄", age: 3}
    //父类调用与子类同名方法,只能调用到父类自己的方法,不能调用子类扩展后的方法
    a.eat()
    a.sleep()

}

在这里插入图片描述

Go语言面向对象详细教程,更高级的应用,持续更新中,感兴趣的朋友可以关注下,ღ( ´・ᴗ・` )比心

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2165094.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vue3:toRaw与markRaw

目录 一.toRaw 1.性质 2.作用 二.markRaw 1.性质 2.作用 三.toRaw的使用 四.markRaw的使用 五.代码示例 在Vue 3中,toRaw和markRaw是两个用于处理响应式对象的全局函数。 一.toRaw 1.性质 toRaw是一个全局函数,它接受一个由reactive或ref生成…

JS面试真题 part6

JS面试真题 part6 26、如何判断一个元素是否在可视区域中27、什么是单点登录?如何实现28、 如何实现上拉加载,下拉刷新29、说说你对正则表达式的理解?应用场景?30、说说你对函数式编程的理解?优缺点 26、如何判断一个元…

Vue74 路由的props配置

笔记 ​ 作用:让路由组件更方便的收到参数 {name:xiangqing,path:detail/:id,component:Detail,//第一种写法:props值为对象,该对象中所有的key-value的组合最终都会通过props传给Detail组件// props:{a:900}//第二种写法:props…

《动手学深度学习》笔记1.11——实战Kaggle比赛:预测房价+详细代码讲解

目录 0. 前言 原书正文 1. 下载和缓存数据集 1.1 download() 下载数据集 1.2 download_extract() 解压缩 2. Kaggle 简介 3. 访问和读取数据集 4. 数据预处理 5. 训练(核心难点) 5.1 get_net() 定义模型-线性回归 5.2 log_rmse() 对数均方根…

见合八方亮相重庆光纤传感大会(OFS China-2024)

2024年9月20日至22日,第十二届中国光纤传感大会(OFS China-2024)在重庆成功举办,该大会旨在展示光纤传感技术在多个领域的最新研究成果,推动该技术的产业化进程。 在本次大会上,天津见合八方光电科技有限公…

JDK1.8与JDK17相互切换

📖 前言:在电脑已经安装jdk17后,发现有些项目不兼容,需要用到以前的jdk1.8,本文介绍简单切换的方法。 🔎 甲骨文jdk1.8官网下载 下载完jdk1.8后,可以将其与jdk17放在同一目录层级下。 搜索栏直…

我眼中的Token2049 是一场加密大秀

今年Token2049,其实我也收到很多来自币圈朋友、项目方或交易所的邀请,都一一婉拒了。因为每年9月,都是我一年来最忙碌的日子。一方面进入金九银十的销售旺季,另外副业也需要谈一些团购业务。 我喜欢Web3,也曾是 #Bitg…

《操作系统 - 清华大学》1 -1:操作系统概述 —— 内容概述

文章目录 1. 内容摘要2. 实验内容 1. 内容摘要 在这里对学习内容做一个整体上的介绍,那在这里包括我们要学习的内容,实验的内容。操作系统课涉及到计算机系统当中的资源管理,所以我们围绕着操作系统的实现来介绍相关内容,那主要分…

Java之路--瓦解逻辑控制与方法使用已是瓮中捉鳖

嗨嗨大家!今天我们来学习逻辑运算和方法的使用~ 目录 一 逻辑控制 1 分支结构 1.1 if语句 1.2 switch 语句 2 循环结构 2.1 while 循环 2.2 for 循环 2.3 do while 循环 2.4 break 2.5 continue 3. 输出输入 二、方法的使用 1 方法定义语法 2 实参和…

NCU-机器学习-作业3:RANK: 0.0代码(No)

想体验一把No.1的快乐吗?话不多说直接上代码。 代码: import osimport pandas as pd from sklearn.preprocessing import StandardScaler from sklearn.svm import SVC import numpy as npdef get_dataset(path):dataset, labels [], []filenames os…

SDK使用指南

本文档主要讲解音视频终端 SDK 产品家族下各子产品的能力支持及购买方式,并提供了相关 Demo 和 SDK 集成资源,具体体验步骤如下: 步骤一:了解产品 1.1 音视频终端 SDK 产品家族介绍 音视频终端 SDK(腾讯云视立方&…

python基础之绘图turtle与分词

python基础 1.学习目的2.实验2.1实验一2.2实验二 3.实验代码及结果 1.学习目的 python库很多,所以我们要在空闲之余学习我们没有遇到的库,就比如turtle和分词库 2.实验 2.1实验一 2.2实验二 3.实验代码及结果 # File: turtle库.py # Author: chen_so…

第L2周:机器学习|线性回归模型 LinearRegression:1. 简单线性回归模型

本文为🔗365天深度学习训练营 中的学习记录博客原作者:K同学啊 任务: ●1. 通过本文学习LinearRegression简单线形回归模型。 ●2. 模仿本文代码,通过鸢尾花花瓣长度预测花瓣宽度。 一、概念 什么是回归 回归的目的是为了预测&…

Vue3入门 - ElementPlus中左侧菜单和Tabs菜单组合联动效果

在Vue3中,ElementPlus是使用比较广泛的UI组件库,提供了丰富的界面元素支持项目开发需求。在后台管理系统中,左侧或顶部的菜单栏通常包含多个子菜单项,通过菜单的展开和收缩功能,用户可以方便地查看或隐藏不需要的菜单项…

Centos7.9安装.Net 8.0框架

1.背景 在Centos7.9编译运行Net8.0项目时,会用到.Net8.0框架。所以我实操了如何在Centos7.9去安装.Net8.0框架。本文记录了相关操作过程,是一个比较好的参考。 2.操作 2.1 安装框架 sudo rpm -Uvh https://packages.microsoft.com/config/centos/8/pa…

一文理解AXI4-lite与AXI4-stream协议

AXI4-lite与AXI4-stream协议 上篇博文《AMBA3.0 AXI总线入门》浅要介绍AXI4总线协议,AXI总线作为一种总线,可以挂载多个主设备(master)和从设备(slave),AXI总线协议定义了主设备和从设备之间如何…

Docker本地部署Chatbot Ollama搭建AI聊天机器人并实现远程交互

文章目录 前言1. 拉取相关的Docker镜像2. 运行Ollama 镜像3. 运行Chatbot Ollama镜像4. 本地访问5. 群晖安装Cpolar6. 配置公网地址7. 公网访问8. 固定公网地址 前言 本文主要分享如何在群晖NAS本地部署并运行一个基于大语言模型Llama 2的个人本地聊天机器人并结合内网穿透工具…

Web安全-SQL注入之联合查询注入

声明 环境 墨者学院-SQL手工注入漏洞测试(MySQL数据库-字符型) 判断是否存在漏洞 http://124.70.64.48:42937/new_list.php?idtingjigonggao and 12-- and 11正常 http://124.70.64.48:42937/new_list.php?idtingjigonggao and 12-- and 12出错,存在字符型注入…

yolov8训练数据集——labelme的json文件转txt文件

yolov8的环境搭建,参考:Home - Ultralytics YOLO Docs 1.把标注好的json文件和jpg放同一个目录下。 2.运行转换脚本文件labelme2yolo.py文件: # -*- coding: utf-8 -*-import os import numpy as np import json from glob import glob im…

python学习笔记(3)——控制语句

控制语句 我们在前面学习的过程中,都是很短的示例代码,没有进行复杂的操作。现在,我们将开始学习流程控制语句。 前面学习的变量、数据类型(整数、浮点数、布尔)、序列(字符串、列表、元组、字 典、集合&am…