Go面向对象

news2025/1/19 20:36:44

前言

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BVGwRsQZ-1681290726009)(../images/Pasted%20image%2020230411223336.png)]

Go也有面向对象

面向对象引入:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-d6CIRyUG-1681290726009)(../images/Pasted%20image%2020230411223356.png)]

用面向对象好啊

结构体定义

GO中的结构体和其他语言中的class是同一个等级的
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0uv76RMy-1681290726009)(../images/Pasted%20image%2020230411223747.png)]

这个就懒得写了 , 直接贴一个

内存分析

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SVvJ4k8g-1681290726010)(../images/Pasted%20image%2020230411223916.png)]

当实例化一个结构体的时候,分配一份内存空间.

结构体实例的创建

package main  
  
import "fmt"  
  
type Teacher struct {  
   Name   string  
   age    int  
   School string  
}  
  
func main() {  
   // 实例化方法一:  
   var t1 Teacher // var a int  
   fmt.Println(t1)  
   // 实例化方法二:  
   var t2 Teacher = Teacher{  
      Name:   "simple",  
      age:    0,  
      School: "ssss",  
   }  
   // 实例化方法三:  
   var t3 Teacher = Teacher{}  
   t3.age = 10  
   //实例化方法四:  
   //t4是一个指针,t4其实指向的就是地址, 应该给这个地址的指向的对象的字段赋值.  
   var t4 *Teacher = new(Teacher)  
   (*t4).Name = "simple"  
   (*t4).age = 24  
   // 为了符合程序员的编程习惯,go提供了简单的赋值方式  
   t4.Name = "sim"  
   t4.age = 25  
   // 实例化方式五:  
   var t5 *Teacher = &Teacher{}  
   (*t5).Name = "simple"  
   (*t5).age = 11  
   t5.School = "ajglajgl"  
}

五种方式的实例化

结构体之间的转换:

  • 结构体是用户自定义的类型, 和其他类型进行转换时需要有完全相同字段(名字,个数, 类型)
package main  
  
import "fmt"  
  
type Student struct {  
   age int  
}  
  
type Person struct {  
   age int  
}  
  
func main() {  
   var s Student = Student{age: 10}  
   var p Person = Person{age: 10}  
   s = Student(p)  
   fmt.Println(s)  
   fmt.Println(p)  
  
}
  • 结构体进行type重新定义(相当于重新取别名),Go认为是新的数据类型,但是相互间可以强转
package main  
  
import "fmt"  
  
type Student struct {  
   age int  
}  
  
type Stu Student  
  
func main() {  
   var s1 Student  
   var s2 Stu  
   s1 = Student(s2)  
   fmt.Println(s1)  
   fmt.Println(s2)  
   }

也就是都要在结构体完全相同的情况下可以进行强转

方法:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4d78CYou-1681290726010)(../images/Pasted%20image%2020230411231033.png)]

上面的结构体绑定方法是用的值传递
用视频中的例子来解释

package main  
  
type Boy struct {  
   Name string  
}  
  
func (b Boy) tets() {  
   b.Name = "complex"  
   println("方法")  
   println(b.Name)  
}  
  
func main() {  
   var boy Boy  
   boy.Name = "simple";  
   boy.tets()  
   println(boy.Name)  
  
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JdjExHDC-1681290726011)(../images/Pasted%20image%2020230411231706.png)]

在方法中去更改Name的值,只是更改了传给方法的结构体的副本的值, 但是原本的结构体并没有被更改.

结构体类型是值类型,在方法调用中,遵守值类型的传递机制,是值拷贝传递方式.

如果程序员希望在方法中,改变了结构体中字段的值, 原来的结构体中的值也被改变,就需要用引用传递的方式来绑定变量了

其实上面的也就是值方法和指针方法的区别
https://zhuanlan.zhihu.com/p/101363361
下面就将上面的值方法改陈指针方法:

package main  
  
type Boy struct {  
   Name string  
}  
  
func (b *Boy) tets() {  
   b.Name = "complex"  
   println("方法")  
   println(b.Name)  
}  
  
func main() {  
   var boy Boy  
   boy.Name = "simple"  
   boy.tets()  
   println(boy.Name)  
  
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2cPOrj1b-1681290726012)(../images/Pasted%20image%2020230411232321.png)]

指定数据类型的方法

package main  
  
type integer int  
  
func (i integer) print() {  
   print("wuwuwuwu")  
}  
  
func main() {  
   var i integer = 1  
   i.print()  
   }

方法的访问控制规则

是和函数一样的,如果首字母小写,只能在本包进行访问, 如果首字母大写了,就可以在其他包中进行访问.

方法的trick

如果一个类型实现了String()这个方法, 那么fmt.Println默认会调用这个变量的String()进行输出.

package main  
  
import "fmt"  
  
type Animal struct {  
   name string  
   age  int  
}  
  
func (a *Animal) String() string {  
   str := fmt.Sprintf("name = %v , age = %v", a.name, a.age)  
   return str  
}  
func main() {  
   animal := Animal{  
      name: "cat",  
      age:  11,  
   }  
   //传入地址,如果绑定了String方法就会自动调用了  
   fmt.Println(&animal)  
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xab00OOr-1681290726012)(../images/Pasted%20image%2020230411233517.png)]

类似Java中的toString方法
在定义结构体的时候,可以把这个方法定义好,常用来作为输出结构体信息的方法

跨包创建结构体示例

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-l7v4oOTz-1681290726012)(../images/Pasted%20image%2020230411234838.png)]

这里的结构体名首字母大写,字段名首字母也要大写,否则没法被外部包访问.
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wncSHKcn-1681290726013)(../images/Pasted%20image%2020230411234936.png)]

工厂模式

上面我们知道,要外部包访问结构体,结构体名首字母必须大写,但是如果小写了,我还是想访问,怎么办?
这里就出现了工厂模式
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MMP6ug4P-1681290726014)(../images/Pasted%20image%2020230411235633.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KETbZFCE-1681290726014)(../images/Pasted%20image%2020230411235619.png)]

可是无论怎么样,在结构体中,字段名的首字母都要大写.
通过调用函数来返回结构体指针.

封装的引入

什么是封装:

封装就是把抽象的字段和对字段的操作封装到一起,数据被保护在内部,程序的其他包通过授权的操作方法,才能对字段进行操作.

封装的好处:

  • 隐藏实现细节
  • 提高对数据的验证,保证安全性

如何实现:

  • 建议将结构体,字段的首字母小写(其他包就不能使用了,类似于private)
  • 给结构体所在的包提供一个工厂模式的函数,首字母小写(类似一个构造函数)
  • 提供一个首字母大写的Set方法(类似其他语言的public),用于对属性的判断和赋值
  • 提供一个首字母大写的Get方法(类似其他语言的public),用于获取属性的值
    Go的封装不是很严格
package student  
  
type person struct {  
   Name string  
   age  int //其他包不能访问  
}  
  
// 定义工厂模式的函数,相当于构造器  
func NewPerson(name string) *person {  
   return &person{  
      Name: name,  
   }  
}  
  
// 定义Set和Get方法对字段进行封装,  
func (p *person) SetAge(age int) {  
   if age > 0 && age < 120 {  
      p.age = age  
  
   } else {  
      print("输入不合法")  
   }  
  
}  
  
func (p *person) GetAge() int {  
   return p.age  
}

这里的person中的两个字段,一个是首字母大写的, 一个是全小写的,Name就可以用工厂模式来弄,而age就只能通过方法来弄了

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VvFhwMme-1681290726014)(../images/Pasted%20image%2020230412154320.png)]

继承:

多个结构体存在相同属性,可以吧这些结构体中抽象出一个结构体,该结构体中定义这些相同的字段,其他结构体就可以不用重复写这些字段了.
在GO中,其他结构体不用重新定义这些属性和方法了,只需要嵌套一个匿名结构体就行.
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NLATnRUq-1681290726014)(../images/Pasted%20image%2020230412154541.png)]

这些继承,父类,子类被Go语言弱化了,但是写代码过程中思维要清楚
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UGJ9Ls2Q-1681290726015)(../images/Pasted%20image%2020230412154855.png)]

上面就是匿名结构体实现继承的图解释.

代码展示一下:

package main  
  
import "fmt"  
  
type Animal struct {  
   Age    int  
   Weight float32  
}  
  
// Animal的方法:  
func (a *Animal) Shout() {  
   fmt.Println("叫")  
}  
  
func (a *Animal) ShowInfo() {  
   fmt.Println(a.Age, a.Weight)  
}  
  
//定义猫的结构体  
type Cat struct {  
   // 继承:用匿名结构体来做  
   Animal  
}  
  
//Cat 的方法  
  
func (c *Cat) Scratch() {  
   fmt.Println("猫的爪子")  
}  
  
func main() {  
   cat := &Cat{Animal{  
      Age:    10,  
      Weight: 10,  
   }}  
   cat.Animal.Age = 11  
   cat.Animal.Weight = 11  
   cat.Animal.Shout()  
   cat.Animal.ShowInfo()  
   cat.Scratch()  
   }

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mwpxImUO-1681290726015)(../images/Pasted%20image%2020230412155533.png)]

注意事项:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TQxnyBqa-1681290726015)(../images/Pasted%20image%2020230412160226.png)]

其实都是比较好理解的,就不做code了
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ODHZclfy-1681290726015)(../images/Pasted%20image%2020230412160356.png)]

第五个如果不做区分是会报错的

第六个
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hK9BbGeT-1681290726015)(../images/Pasted%20image%2020230412160657.png)]

组合类型
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YwMisTA1-1681290726015)(../images/Pasted%20image%2020230412160948.png)]

这个组合类型不是继承关系

接口:

package main  
  
import (  
   "fmt"  
)  
  
//定义一个接口:接口一些规则,规范,某种能力  
//这里是抽象理解一个说你好的能力  
type Sayhello interface {  
   //声明一个没有实现的方法  
   Sayhello()  
}  
  
//接口的实现:定义一个结构体  
//中国人:  
type Chinese struct {  
}  
  
//实现接口的方法  
func (c *Chinese) Sayhello() {  
   fmt.Println("你好")  
}  
  
type English struct {  
}  
  
func (e *English) Sayhello() {  
   println("hi")  
}  
  
func main() {  
   chinese := &Chinese{}  
   chinese.Sayhello()  
   english := English{}  
   english.Sayhello()  
}
你好
hi

所以就是如果一个结构体实现了接口中的所有定义的方法,这个结构体就实现了这个接口.

看看这个接口可做什么?

package main  
  
import (  
   "fmt"  
)  
  
// 定义一个接口:接口一些规则,规范,某种能力  
// 这里是抽象理解一个说你好的能力  
type Sayhello interface {  
   //声明一个没有实现的方法  
   Sayhello()  
}  
  
// 接口的实现:定义一个结构体  
// 中国人:  
type Chinese struct {  
}  
  
// 实现接口的方法  
func (c *Chinese) Sayhello() {  
   fmt.Println("你好")  
}  
  
type English struct {  
}  
  
func (e *English) Sayhello() {  
   println("hi")  
}  
  
// 定义一个函数:用来专门向各个国家的人打招呼的函数,接收具备Sayhello接口的能力的变量  
func greet(s Sayhello) {  
   s.Sayhello()  
}  
  
func main() {  
   chinese := &Chinese{}  
   chinese.Sayhello()  
   english := &English{}  
   english.Sayhello()  
   greet(chinese)  
   greet(english)  
  
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ElnXUWTF-1681290726015)(../images/Pasted%20image%2020230412162342.png)]

接口是一个隐式的实现.
要求并不严格
接口的目的是为了让定义规范
其实也和下面的多态有关系

多态

基本介绍:

变量(实例)具有多种形态.面向对象的第三大特征, 在Go中,多态是通过接口来实现的.
可以按照统一的接口来调用不同的实现. 这时接口变量就呈现不同的形态.

案例

就是上面接口中的不同国家的人的打招呼

package main  
  
import (  
   "fmt"  
)  
  
// 定义一个接口:接口一些规则,规范,某种能力  
// 这里是抽象理解一个说你好的能力  
type Sayhello interface {  
   //声明一个没有实现的方法  
   Sayhello()  
}  
  
// 接口的实现:定义一个结构体  
// 中国人:  
type Chinese struct {  
}  
  
// 实现接口的方法  
func (c *Chinese) Sayhello() {  
   fmt.Println("你好")  
}  
  
type English struct {  
}  
  
func (e *English) Sayhello() {  
   println("hi")  
}  
  
// 定义一个函数:用来专门向各个国家的人打招呼的函数,接收具备Sayhello接口的能力的变量  
func greet(s Sayhello) {  
   s.Sayhello()  
}  
  
func main() {  
   chinese := &Chinese{}  
   english := &English{}  
   greet(chinese)  
   greet(english)  
  
}

接口体现多态特征

  • 多态参数:
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ys1CHaj4-1681290726016)(../images/Pasted%20image%2020230412164853.png)]

  • 多态数组
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bemwcyeH-1681290726016)(../images/Pasted%20image%2020230412165214.png)]

断言

什么是断言:

Go语言里面有一个语法,可以直接判断是否是该类型的变量:value , ok = element.(T), 这里的value就是变量的值, ok是一个bool类型, element是interface变量, T是断言的类型

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

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

相关文章

计组第一章——计算机组成的基本认识

计算机——> 数值计算——> 处理电信号——> 基本单元&#xff08;逻辑元件&#xff09; 电子管——> 晶体管——>中小规模集成电路 ——>大规模&#xff0c;超大规模集成电路 机器字长&#xff1a;计算机一次整数运算所能处理的二进制位数 解析存储器中的程…

Vue——组件 v-model

目录 ​ v-model 的参数​ 多个 v-model 绑定​ 处理 v-model 修饰符​ v-model 可以在组件上使用以实现双向绑定。 首先让我们回忆一下 v-model 在原生元素上的用法&#xff1a; <input v-model"searchText" />在代码背后&#xff0c;模板编译器会对 v-…

工程日记的感悟

我个人很喜欢工程日记&#xff0c;好像一片自己一亩三分地一样&#xff0c;自己想弄些啥&#xff0c;就弄些啥。 人需要这份自由&#xff0c;需要这份能动性&#xff0c;因为人是创造者。 在《从小工到专家》的书中所要求的条目之中&#xff0c;有一条&#xff0c;就是工程日志…

最详细的Ubuntu服务器搭建Stable-Diffusion教程(无显卡,仅用CPU)

1. 首先安装基本工具 # 安装python环境 sudo apt install wget git若已经安装过请忽略 2. 安装miniconda&#xff08;也可以自己下载python&#xff09; 下载最新的安装包 wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh执行安装 ./Minicon…

NumPy 秘籍中文第二版:十二、使用 NumPy 进行探索性和预测性数据分析

原文&#xff1a;NumPy Cookbook - Second Edition 协议&#xff1a;CC BY-NC-SA 4.0 译者&#xff1a;飞龙 在本章中&#xff0c;我们涵盖以下秘籍&#xff1a; 探索气压探索日常气压范围研究年度气压平均值分析最大可见度用自回归模型预测气压使用移动平均模型预测气压研究年…

HTML svg 之<path>使用

<path> 元素用于定义一个路径。 一、命令 下面的命令可用于路径数据&#xff1a; 命令字母示意描述(小写表示相对于上个坐标的位移,相对路径)M(m) x ymoveto移动到(x,y)L(l) x ylineto画一条直线到(x,y)H(h) xhorizontal lineto水平画一条直线到 Xv(v) yvertical linet…

CVE漏洞复现-CVE-2022-22965-Spring-RCE漏洞

CVE-2022-22965-Spring-RCE漏洞 漏洞概况与影响 Spring framework 是Spring 里面的一个基础开源框架&#xff0c;其目的是用于简化 Java 企业级应用的开发难度和开发周期,2022年3月31日&#xff0c;VMware Tanzu发布漏洞报告&#xff0c;Spring Framework存在远程代码执行漏洞…

JAVAWeb05-Tomcat

1. Tomcat 1.1 概述 1.1.1 官方文档 地址: https://tomcat.apache.org/tomcat-8.0-doc/ 1.1.2 WEB 开发介绍 WEB&#xff0c;在英语中 web 表示网/网络资源(页面,图片,css,js)意思&#xff0c;它用于表示 WEB 服务器(主机)供浏览器访问的资源WEB 服务器(主机)上供外界访问…

终于见识到 Python 的天花板。。

Python 有很多衍生方向&#xff0c;比如 web 开发、网络爬虫、数据分析、数据挖掘、机器学习、人工智能等等&#xff0c;就业范围是很广的&#xff0c;Python 相较于别的编程语言对小白入门还是很友好的&#xff0c; Python 入门推荐这份学习资料&#xff1a;PYTHON全案例实践…

【基础知识】PCB布局设计入门步骤

准备是成功的基石&#xff0c;在PCB设计中也是如此。改进和增长将伴随经验&#xff0c;首先做好准备能够充分利用经验获得成功。为了帮助你做好准备&#xff0c;下面分享一些基本的PCB布局设计步骤。 从良好的原材料入手是您PCB布局设计的第一步 无论打算执行什么任务&#xff…

Vue3——一文入门Vue3

Vue3的优势 1. 性能的提升 打包大小减少41% 初次渲染快55%&#xff0c;更新渲染快133% 内存减少54% … 2. 源码的升级 使用Proxy代替defineProperty实现响应式 重写虚拟DOM的实现和Tree-Shaking … 3. 拥抱TypeScript Vue3可以更好的支持TypeScript 4. 新的特性 1.C…

Java 进阶(2) Collection集合

集合的概念 概念&#xff1a;集合是java中提供的⼀种容器&#xff0c;可以⽤来存储多个数据。 数组&#xff1a;存储⼀组相同数据类型的数据结构。 局限&#xff1a;定长 集合&#xff1a;动态存放多个对象。 动态&#xff1a;集合的⼤⼩随着存储的数据量⽽改变。 多个&…

python界面开发案例:制作一个计算器软件

前言 大家早好、午好、晚好吖 ❤ ~欢迎光临本文章 在我们手机上大家都有一个计算器&#xff0c;对吧 那它这功能是怎么实现的呢&#xff1f; 今天我们在电脑上来实现一个电脑端计算器界面~ 开发环境&#xff1a; Python 3.8 / 编译器 Pycharm 2021.2版本 / 编辑器 本文所有…

leedcode刷题(5)

各位朋友们&#xff0c;大家好&#xff0c;今天是我leedcode刷题的第五篇&#xff0c;我们一起来看看吧。 文章目录栈的压入&#xff0c;弹出序列题目要求用例输入提示做题思路代码实现C语言代码实现Java代码实现最小栈题目要求用例输入提示做题思路代码实现Java代码实现栈的压…

MATLAB绘制局部放大图

MATLAB绘制局部放大图 1 工具准备 MATLAB官网-ZoomPlot(Kepeng Qiu. Matlab Central, 2022) 初始数据图绘制完成后&#xff0c;调用以下代码&#xff1a; %% 添加局部放大 zp BaseZoom(); zp.plot;1.1 具体绘制步骤 具体绘制步骤如下&#xff1a; 通过鼠标左键框选作图区…

STM-32:I2C通信协议—软件I2C读写MPU6050

目录一、I2C通信二、硬件电路三、I2C时序基本单元3.1起始和终止3.1.1起始条件3.1.2终止条件3.2发送一个字节3.3接收一个字节3.4发送应答3.5接收应答四、I2C时序4.1指定地址写4.2当前地址读4.2指定地址读4.3连续读与写五、MPU6050简介六、MPU6050参数七、硬件电路八、MPU6050框图…

用英语翻译中文-汉字英文翻译

中文转英语翻译 作为一款高效、准确的中文转英语翻译软件&#xff0c;我们的产品可以帮助全球用户更好地沟通和合作&#xff0c;实现跨文化交流。 在全球化的今天&#xff0c;中英文翻译已经成为商务、学术、娱乐等各个领域不可或缺的一部分。我们的中文转英语翻译软件是为了…

大学生必备神器

大学生要掌握的办公软件因专业和工作需求而异&#xff0c;但是以下是一些普遍适用于大学生的办公软件&#xff0c;可以帮助提高学习和工作效率&#xff0c;今天就给大家推荐几款大学生常用的软件。 1.OneDrive 这是微软出品的云存储产品&#xff0c;与百度网盘有些类似&#…

龙芯中科官方宣布,龙芯中科企业办公信息化平台全面完成国产化替代

4月4日&#xff0c;龙芯中科官方宣布&#xff0c;龙芯中科企业办公信息化平台全面完成国产化替代。龙芯 ERP 系统全系统使用国产化平台&#xff0c;私有化部署于基于龙芯 3C5000 服务器集群的虚拟化云平台上&#xff0c;使用自研 Loongnix 操作系统、自研 LoongDB 数据库及龙芯…

SpringBoot集成Milo库实现OPC UA客户端:连接、遍历节点、读取、写入、订阅与批量订阅

背景 前面我们搭建了一个本地的 PLC 仿真环境&#xff0c;并通过 KEPServerEX6 读取 PLC 上的数据&#xff0c;最后还使用 UAExpert 作为OPC客户端完成从 KEPServerEX6 这个OPC服务器的数据读取与订阅功能。在这篇文章中&#xff0c;我们将通过 SpringBoot 集成 Milo 库实现一…