Go后端开发 -- 面向对象特征:结构体 继承 多态 interface

Go后端开发 – 面向对象特征:结构体 && 继承 && 多态 && interface

文章目录

  • Go后端开发 -- 面向对象特征:结构体 && 继承 && 多态 && interface
  • 一、Go的结构体
    • 1.结构体的声明和定义
    • 2.结构体传参
  • 二、将结构体变成类
    • 1.向结构体中添加成员函数
    • 2.结构体定义的访问权限问题
  • 三、Golang面向对象的继承
  • 四、interface接口与多态
    • 1.由interface实现多态
    • 2.通用万能类型
    • 3.类型断言


一、Go的结构体

1.结构体的声明和定义

  • type用来声明数据类型
//声明一种新的数据类型myint,是int的一个别名
type myint int
  • 使用type定义结构体
  • 对于结构体对象:
    可以先定义后初始化;
    也可以直接在{}中初始化
package mainimport "fmt"// 定义一个结构体
type Book struct {title  stringauthor string
}func main() {//可以先定义后初始化var book1 Bookbook1.title = "Golang"book1.author = "李四"//也可以直接在{}中初始化book2 := Book{title: "c++", author: "王五"}fmt.Println(book1)fmt.Println(book2)
}

在这里插入图片描述

2.结构体传参

  • 值传参
    传递的是结构体的拷贝,原结构体不会发生改变
package mainimport "fmt"// 定义一个结构体
type Book struct {title  stringauthor string
}func main() {var book1 Bookbook1.title = "Golang"book1.author = "李四"fmt.Println(book1)changeBook(book1)fmt.Println(book1)
}func changeBook(book Book) {book.author = "张三"
}

在这里插入图片描述

  • 引用传递
    传递的是结构体的指针,原结构体的值会改变
package mainimport "fmt"// 定义一个结构体
type Book struct {title  stringauthor string
}func main() {var book1 Bookbook1.title = "Golang"book1.author = "李四"fmt.Println(book1)changeBook(&book1)fmt.Println(book1)
}func changeBook(book *Book) {book.author = "张三"
}

在这里插入图片描述

二、将结构体变成类

1.向结构体中添加成员函数

type Hero struct {Name  stringAd    intLevel int
}func (this Hero) GetName() string {return this.Name
}
  • GetName这个函数前面的(this Hero)表明这个函数是绑定于Hero这个结构体中的成员函数,可以通过this这个参数调用结构体中的成员
package mainimport "fmt"type Hero struct {Name  stringAd    intLevel int
}func (hero Hero) GetName() string {return hero.Name
}func (hero Hero) SetName(newName string) {hero.Name = newName
}func main() {hero1 := Hero{Name: "zhangsan", Ad: 25, Level: 3}fmt.Println(hero1)name1 := hero1.GetName()fmt.Println(name1)hero1.SetName("超人")fmt.Println(hero1)
}

在这里插入图片描述
可以看到getName可以获取结构体对象中的成员变量,但是setName函数没有改变对象中的值

  • 因为hero这个参数是调用该方法的对象的一个拷贝
    在这里插入图片描述
  • 将所有的hero参数都改为*Hero类型,那么hero参数就是调用该方法的对象的指针了,指向该对象的地址空间,能够改变对象的成员变量的值
  • 因此对所有的成员函数,该参数都应该定义为指针类型的参数
package mainimport "fmt"type Hero struct {Name  stringAd    intLevel int
}func (hero *Hero) GetName() string {return hero.Name
}func (hero *Hero) SetName(newName string) {hero.Name = newName
}func main() {hero1 := Hero{Name: "zhangsan", Ad: 25, Level: 3}fmt.Println(hero1)name1 := hero1.GetName()fmt.Println(name1)hero1.SetName("超人")fmt.Println(hero1)
}

在这里插入图片描述

2.结构体定义的访问权限问题

上面实例的结构体类型Hero的首字母是大写的
go语言的封装是针对包来封装的,类的公有和私有都是针对包来的

  • 类名首字母大写,代表其他包可以访问该类,可以定义该类对象
    在这里插入图片描述

  • 类的属性首字母大写,表示该属性是对外能够访问的(public),否则只能类的内部访问(private)
    在这里插入图片描述

三、Golang面向对象的继承

go中的面向对象的继承没有公有、私有继承,只有一种类型的继承

实例:

package mainimport "fmt"type Human struct {name stringsex  string
}func (human *Human) Eat() {fmt.Println("Human.Eat()...")
}func (human *Human) Walk() {fmt.Println("Human.Walk()...")
}type Superman struct {Human //表示Superman类继承了Human类的方法level int
}// 重定义父类方法
func (superman *Superman) Eat() {fmt.Println("Superman.Eat()...")
}// 定义子类的新方法
func (superman *Superman) Fly() {fmt.Println("Superman.Fly()...")
}func main() {h1 := Human{name: "zhangsan", sex: "male"}h1.Eat()h1.Walk()//定义一个子类对象s1 := Superman{Human{"蝙蝠侠", "male"}, 3}s1.Eat()  //子类重写的成员函数s1.Walk() //父类成员函数s1.Fly()  //子类独有成员函数
}

在这里插入图片描述

  • 上述实例中,Superman继承了Human类,也就是继承了父类的全部成员
  • 子类可以对父类的成员函数进行重写,也可以调用父类的成员函数
  • 子类可以直接访问父类的成员变量
    在这里插入图片描述

四、interface接口与多态

1.由interface实现多态

Golang中的多态需要依赖interface接口实现;

  • interface类型,本质是一个父类指针,用于定义接口,底层是指针指向函数列表
type AnimalIF interface {Sleep()GetColor() string //获取动物颜色GetType() string  //获取动物类别
}
  • 如果一个类实现了interface中的所有方法,就代表该类实现了当前的interface接口,就可以实现多态,interface类型的的指针就可以指向该类的对象了
  • 若一个类没有完全重写interface中的所有方法,则interface指针无法指向该类

实例

package interface_goimport "fmt"// 本质是一个父类指针,用于定义接口,底层是指针指向函数列表
type AnimalIF interface {Sleep()GetColor() string //获取动物颜色GetType() string  //获取动物类别
}// 具体的类
type Cat struct {//无需在子类中继承interface,只需要实现interface的方法,就可以实现多态//这样就可以用interface的指针去指向Cat对象color string //猫的颜色
}// 重写interface接口中的方法
// Cat类重写了interface中的所有方法,就代表该类实现了当前的接口
// 若Cat类没有完全重写interface中的所有方法,则interface指针无法指向该类
func (c *Cat) Sleep() {fmt.Println("Cat is sleep")
}func (c *Cat) GetColor() string {return c.color
}func (c *Cat) GetType() string {return "Cat"
}type Dog struct {color string
}func (d *Dog) Sleep() {fmt.Println("Dog is sleep")
}func (d *Dog) GetColor() string {return d.color
}func (d *Dog) GetType() string {return "Dog"
}// 使用父类指针来接受子类对象
func showAnimal(animal AnimalIF) {animal.Sleep()fmt.Println("color = ", animal.GetColor())fmt.Println("type = ", animal.GetType())
}func Interface() {var animal AnimalIF     //接口的数据类型,也就是父类的指针animal = &Cat{"yellow"} //通过匿名对象的指针给接口赋值,animal.Sleep()          //调用的就是Cat的Sleep()方法animal = &Dog{"black"}fmt.Println(animal.GetColor()) //调用的就是Dog的GetColor()方法,多态的现象
}

在这里插入图片描述

  • 上述实例中,创建了名为AnimalIF的interface接口,包含三个方法

  • Cat和Dog类重写了AnimalIF的所有接口,因此AnimalIF指针可以指向Cat和Dog类的对象,进而实现多态

  • 还可以通过AnimalIF类型的指针,接受Cat和Dog类对象的地址,这样也可以体现出多态

package interface_goimport "fmt"// 本质是一个父类指针,用于定义接口,底层是指针指向函数列表
type AnimalIF interface {Sleep()GetColor() string //获取动物颜色GetType() string  //获取动物类别
}// 具体的类
type Cat struct {//无需在子类中继承interface,只需要实现interface的方法,就可以实现多态//这样就可以用interface的指针去指向Cat对象color string //猫的颜色
}// 重写interface接口中的方法
// Cat类重写了interface中的所有方法,就代表该类实现了当前的接口
// 若Cat类没有完全重写interface中的所有方法,则interface指针无法指向该类
func (c *Cat) Sleep() {fmt.Println("Cat is sleep")
}func (c *Cat) GetColor() string {return c.color
}func (c *Cat) GetType() string {return "Cat"
}type Dog struct {color string
}func (d *Dog) Sleep() {fmt.Println("Dog is sleep")
}func (d *Dog) GetColor() string {return d.color
}func (d *Dog) GetType() string {return "Dog"
}// 使用父类指针来接受子类对象
func showAnimal(animal AnimalIF) {animal.Sleep()fmt.Println("color = ", animal.GetColor())fmt.Println("type = ", animal.GetType())
}func Interface() {c1 := Cat{"yellow"}d1 := Dog{"white"}showAnimal(&c1)showAnimal(&d1)
}

在这里插入图片描述

2.通用万能类型

interface{}空接口:为Golang的万能类型,基本类型如int, string, float32, float64, struct等都实现了interface{}(因为空接口中没有具体的接口),因此interface{}这种类型的变量可以引用任意的数据类型

实例:

package interface_goimport "fmt"// arg这个参数可以接受任意的类型
func allType(arg interface{}) {fmt.Println(arg)
}type Book struct {name   stringauthor string
}func Interface() {book1 := Book{"shijie", "zhangsan"}allType(book1)allType(120)allType(12.5848)
}

在这里插入图片描述

  • 在上述实例中,函数allType的参数arg的类型是interface{},是通用万能类型,能够接受任意类型的参数

3.类型断言

Golang为interface{}类型提供了类型断言,用于判断interface{}类型变量引用的参数底层数据类型是什么

  • 断言的格式为:
    value, ok := arg.(string)
    如果断言成功,即arg是string类型,则value被赋值为string类型的arg的值,ok被赋值为true;否则value为空,ok为false

实例:

package interface_goimport "fmt"// arg这个参数可以接受任意的类型
func allType(arg interface{}) {fmt.Println(arg)//interface{}改如何区分 此时引用的底层数据类型到底是什么value, ok := arg.(string)if ok {fmt.Println("arg is string type, value = ", value)} else {fmt.Println("arg is not string type")}
}type Book struct {name   stringauthor string
}func Interface() {book1 := Book{"shijie", "zhangsan"}allType(book1)allType(120)allType(12.5848)
}

在这里插入图片描述

  • interface{}断言可以配合switch语句使用,switch t := arg.(type) { }是switch语句的独有断言方式,arg.(type)不可脱离switch语句单独使用
package interface_goimport "fmt"// arg这个参数可以接受任意的类型
func allType(arg interface{}) {switch t := arg.(type) {case string:fmt.Println("arg is string type, value = ", t)case int:fmt.Println("arg is int type, value = ", t)case float32:fmt.Println("arg is float32 type, value = ", t)case float64:fmt.Println("arg is float64 type, value = ", t)default:fmt.Println("arg is unexpected type")}
}type Book struct {name   stringauthor string
}func Interface() {book1 := Book{"shijie", "zhangsan"}allType(book1)allType(120)allType(12.5848)
}

在这里插入图片描述

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

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

相关文章

简易机器学习笔记(十一)opencv 简易使用-人脸识别、分类任务

前言 前段时间摸了下机器学习,然后我发现其实openCV还是一个很浩瀚的库的,现在也正在写一篇有关yolo的博客,不过感觉理论偏多,所以在学yolo之前先摸一下opencv,简单先写个项目感受感受opencv。 流程 openCV实际上已…

Go interface基础

接口类型是对其它类型行为的概括与抽象。通过使用接口,我们可以写出更加灵活和通用的函数,这些函数不用绑定在一个特定的类型实现上。 很多面向对象的语言都有接口这个概念,Go 语言的接口的独特之处在于它是隐式实现。换句话说,对…

maven导入无法拉取所需依赖

maven导入无法拉取所需依赖 1.原因2.解决搞定收工&#xff01; 1.原因 公司使用的是gradle&#xff0c;配置的私有云&#xff0c;maven里面配置私有云完全使用不了&#xff0c;无论配置国内还是国外的&#xff0c;导入的项目报错拉不到jar包。 <mirror><id>mirro…

Dhcp中继ensp

拓扑图 <Huawei>system-view [Huawei]sysname SW1 [SW1]vlan batch 10 20 [SW1]int e0/0/1 #配置access接口 [SW1-Ethernet0/0/1]port link-type access [SW1-Ethernet0/0/1]port default vlan 10 [SW1-Etherne…

[C#]利用paddleocr进行表格识别

【官方框架地址】 https://github.com/PaddlePaddle/PaddleOCR.git 【算法介绍】 PaddleOCR表格识别是PaddlePaddle开源项目中的一个强大功能&#xff0c;它利用深度学习技术实现了对各类表格的高精度识别。PaddleOCR表格识别能够处理各种复杂的表格&#xff0c;包括但不限于…

【语音助手】语音识别框架的简单介绍

文章目录 ASR 框架常见的ASR框架用于嵌入式领域的ASR框架 NLP 框架常用NLP框架用于嵌入式领域的NLP框架 TTS 框架常见的TTS 框架用于嵌入式领域的TTS 框架 ASR&#xff1a;语音识别&#xff08;ASR&#xff09;是一种将语音信号转换为文本的技术。NLP&#xff1a;自然语言处理。…

cartopy,一个非常好用的 Python 库!

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com 大家好&#xff0c;今天为大家分享一个非常好用的 Python 库 - cartopy。 Github地址&#xff1a;https://github.com/SciTools/cartopy 地图数据可视化在许多领域中都是至关重要的&#xff0c;无论是用于气象学…

IDEA2023的激活与安装(全网最靠谱,最快捷的方式)

前言&#xff1a; 相信很多小伙伴已经开始了java的学习之旅&#xff0c;想要更快乐的学习当然少不了IDEA这个得力的开发工具软件。但是IDEA是付费的&#xff0c;免费版功能有太少&#xff0c;怎么才能既免费&#xff0c;又能使用上正式版呢&#xff01;当然还是激活啦&#xf…

json 读取中文、保存为中文的json文件

pycharm 打开的json文件 通过代码读取中文文件 保存中文的json文件&#xff1a; import jsonwith open(garbage_classification.json,encodingutf-8-sig,moder) as f:data json.load(f) # print(data) {0: 可回收物_金属食品罐, 1: 其他垃圾_PE塑料袋, 2: 其他垃圾_污损塑…

设备树下Led驱动实验-向设备树文件添加Led设备节点

一. 简介 前面简单学习了设备树文件的内容&#xff0c;语法&#xff0c;以及如何向设备树文件中添加设备节点信息。学习了驱动开发时&#xff0c;会使用到的设备树常用OF操作函数。本文我们就开始第一个基于设备树的 Linux 驱动实验-LED驱动实现。 本文具体学习在设备树文件添…

vlc播放rtsp视频流

简单记录一下项目中用到的浏览器内嵌vlc播放rtsp视频流 首先使用object标签&#xff0c;关于object标签的介绍&#xff0c;放一张图 页面设置 <object class"vlc-box" ref"vlc" type"application/x-vlc-plugin"windowless"true"pl…

yum仓库和nfs

目录 一、yum 1.1.yum概述 1.2.yum实现过程 1.3.yum配置文件 1.4.仓库设置文件/etc/yum.repos.d/*.repo 1.5.yum命令 二、NFS 2.1.NFS介绍 2.2.NFS特点 2.3.NFS优势 2.4.NFS原理 2.5.NFS共享存储服务 一、yum 1.1.yum概述 基于RPM包构建的软件更新机制 可以自动…

推荐三个非常好用的视频转文字工具

在处理视频文件时&#xff0c;有时我们需要将视频中的语音内容转换为文字形式&#xff0c;以便于整理、编辑或搜索。传统的视频转文字方法往往需要耗费大量时间和人力&#xff0c;而且准确度难以保证。现在&#xff0c;有了水印云等视频转文字神器&#xff0c;我们可以快速、准…

JS | JS调用EXE

JS | JS调用EXE 网上洋洋洒洒一大堆文章提供,然我还是没找打合适的方案: 注册表方案做了如下测试(可行但是不推荐?): 先,键入文件名为 myprotocal.reg 的注册表,并键入一下信息: Windows Registry Editor Version 5.00[HKEY_CLASSES_ROOT\openExe] //协议名…

开发知识付费系统源码详解:搭建内容付费平台的完整指南

本篇文章&#xff0c;小编将继续讲解如何开发知识付费系统&#xff0c;并通过详细的源码解析为您提供搭建内容付费平台的完整指南。 一、技术选型 在搭建知识付费系统之前&#xff0c;首先需要选择适合项目的技术栈。我们将详细介绍前后端技术的选择&#xff0c;包括数据库、…

C#编程-了解进程的通信

了解进程的通信 逻辑上一个应用程序内的所有线程都包含在进程内。这是应用程序运行的操作系统单元。进程是程序的一个运行实例。运行时在同一计算机内或通过网络的进程间通信被称为进程内通信。要允许进程间通信,需要使用特殊的技术和机制。 考虑一个您打文档的场景。您使用…

快速知识付费平台搭建,一分钟搭建你的专属知识服务平台

产品服务 线上线下课程传播 线上线下活动管理 项目撮合交易 找商机找合作 一对一线下交流 企业文化宣传 企业产品销售 更多服务 实时行业资讯 动态学习交流 分销代理推广 独立知识店铺 覆盖全行业 个人IP打造 独立小程序 私域运营解决方案 公域引流 营销转化 …

3D Guassians Splatting相关解读

从已有的点云模型出发&#xff0c;以每个点为中心&#xff0c;建立可学习的高斯表达&#xff0c;用Splatting即抛雪球的方法进行渲染&#xff0c;实现高分辨率的实时渲染。 1、主要思想 1.引入了一种各向异性&#xff08;anisotropic&#xff09;的3D高斯分布作为高质量、非结…

transbigdata笔记:轨迹停止点和行程提取

1 traj_stay_move——标识停靠点和行程 1.1 方法介绍 如果两个连续轨迹数据点之间的持续时间超过设定的阈值&#xff0c;将其视为停靠点。两个停靠点之间的时间段被视为一个行程 1.2 使用方法 transbigdata.traj_stay_move(data, params, col[ID, dataTime, longitude, lat…

[自动驾驶算法][从0开始轨迹预测]:二、自动驾驶系统中常用的坐标系及相应的转换关系

自动驾驶中常见的坐标系与坐标转换 1. 传感器坐标系1.1 相机坐标系统1) 相机相关基础知识2) 相机各坐标系图像/像素坐标系相机坐标系像平面坐标系 3) 相机各坐标系之间的转换像平面坐标系到像素坐标系的转换&#xff08;平移缩放变换&#xff09;相机坐标系转像平面坐标系&…