Go 语言(三)【面向对象编程】

1、OOP

首先,Go 语言并不是面向对象的语言,只是可以通过一些方法来模拟面向对象

1.1、封装

Go 语言是通过结构体(struct)来实现封装的。

1.2、继承

继承主要由下面这三种方式实现:

1.2.1、嵌套匿名字段

//Address 地址结构体
type Address struct {Province stringCity     string
}//User 用户结构体
type User struct {Name    stringGender  stringAddress //匿名字段
}func main() {var user2 Useruser2.Name = "小王子"user2.Gender = "男"user2.Address.Province = "山东"    // 匿名字段默认使用类型名作为字段名user2.City = "威海"                // 匿名字段可以省略fmt.Printf("user2=%#v\n", user2) //user2=main.User{Name:"小王子", Gender:"男", Address:main.Address{Province:"山东", City:"威海"}}
}

1.2.2、嵌套结构体

//Address 地址结构体
type Address struct {Province stringCity     string
}//User 用户结构体
type User struct {Name    stringGender  stringAddress Address
}func main() {user1 := User{Name:   "小王子",Gender: "男",Address: Address{Province: "山东",City:     "威海",},}fmt.Printf("user1=%#v\n", user1)//user1=main.User{Name:"小王子", Gender:"男", Address:main.Address{Province:"山东", City:"威海"}}
}

1.2.3、嵌套匿名结构体指针

//Animal 动物
type Animal struct {name string
}func (a *Animal) move() {fmt.Printf("%s会动!\n", a.name)
}//Dog 狗
type Dog struct {Feet    int8*Animal //通过嵌套匿名结构体实现继承
}func (d *Dog) wang() {fmt.Printf("%s会汪汪汪~\n", d.name)
}func main() {d1 := &Dog{Feet: 4,Animal: &Animal{ //注意嵌套的是结构体指针name: "乐乐",},}d1.wang() //乐乐会汪汪汪~d1.move() //乐乐会动!
}

        而既然结构体可以继承,那么结构体就必须有方法,Go 语言的方法必须在方法名前面声明调用者。子类可以重写父类方法:如果在子结构体(或任何类型)上定义了一个与父结构体中同名的方法,那么这个方法就会覆盖父结构体中的方法。这就实现了重写。

1.3、多态

多态:一个事物拥有多种形态就是多态!

有多态就必须要有接口,因为接口就是为了解决多态这个问题的:

1.3.1、接口

  • Go 语言提供了接口数据类型
  • 接口就是把一些共性的方法放在一起定义
  • Go 语言中的接口是隐式声明的(相比较 Java 会用 implements 关键字显示声明)
  • 只有实现类把接口的方法全部实现才算实现了这个接口

接口的实现类都拥有多态的特性,因为它除了是自己还是它的接口类型。

package mainimport "fmt"// 接口
type USB interface {input()output()
}// 结构体
type Mouse struct {name string
}
// 实现接口:实现了接口的所有方法才算实现了这个接口
func (mouse Mouse) input(){fmt.Println(mouse.name,"鼠标输入")
}
func (mouse Mouse) output(){fmt.Println(mouse.name,"鼠标输出")
}type KeyBoard struct {name string
}
func (keyBoard KeyBoard) input(){fmt.Println(keyBoard.name,"键盘输入")
}
func (keyBoard KeyBoard) output(){fmt.Println(keyBoard.name,"键盘输出")
}func test(u USB) {u.input()u.output()
}func main() {mouse := Mouse{name: "罗技"}test(mouse)keyBoard := KeyBoard{name: "艾石头"}test(keyBoard)// 通过接口创建子类实例var usb USB = Mouse{name: "外星人"}usb.input()// 但是接口是无法使用实现类的属性的
}

 运行结果:

罗技 鼠标输入
罗技 鼠标输出
艾石头 键盘输入
艾石头 键盘输出外星人 鼠标输入

1.3.2、空接口 

空接口不包含任何方法,所以所有的结构体都默认实现了空接口(类似于 Java 的 Object)!

所谓的空接口,就是:

type 接口名称 interface{}

go 语言中的 any 其实就是空接口,我们可以在源码中看到:

        如果我们定义一个方法或者函数它可以传入一个空接口类型,那么就相当于任何类型都可以传入这个方法或函数,因为任何结构体类型的都实现了空接口。比如我们 go 语言中的打印方法的参数就都是 any ... 。

2、接口

        上面只是描述了接口是怎么实现多态的,但是对接口的用法并没有深入介绍,这里我们详细介绍接口的用法。

2.1、接口的定义

type 接口名 interface{方法名1(参数列表) (返回值列表)方法名2(参数列表) (返回值列表)// ...
}

需要注意的是:

  • 接口类型名:Go语言的接口在命名时,一般会在单词后面添加er,如有写操作的接口叫Writer,有关闭操作的接口叫closer等。接口名最好要能突出该接口的类型含义。
  • 方法名当方法名首字母是大写且这个接口类型名首字母也是大写时,这个方法可以被接口所在的包(package)之外的代码访问。
  • 参数列表、返回值列表:参数列表和返回值列表中的参数变量名可以省略。

2.2、接口类型变量

所谓的接口类型变量就就像 Java 中的:

Map<String,Integer> map;
HashMap<String,Integer> map1 = new HashMap<>();
TreeMap<String,Integer> map2 = new TreeMap<>();
map = m1;
map = m2;

这里的变量 map 就是一个接口变量,接口变量可以通过任何实现类来赋值。

2.3、接口的嵌套

Go 语言中的接口可以组合嵌套,这是区别于 Java 很大的一点。在 Go标准库 io 源码中就有很多接口之间互相组合的示例:

// src/io/io.gotype Reader interface {Read(p []byte) (n int, err error)
}type Writer interface {Write(p []byte) (n int, err error)
}type Closer interface {Close() error
}// ReadWriter 是组合Reader接口和Writer接口形成的新接口类型
type ReadWriter interface {ReaderWriter
}// ReadCloser 是组合Reader接口和Closer接口形成的新接口类型
type ReadCloser interface {ReaderCloser
}// WriteCloser 是组合Writer接口和Closer接口形成的新接口类型
type WriteCloser interface {WriterCloser
}

同时,接口也可以作为结构体的字段,就像 Java 中 Map 可以作为对象属性一样:

// src/sort/sort.go// Interface 定义通过索引对元素排序的接口类型
type Interface interface {Len() intLess(i, j int) boolSwap(i, j int)
}// reverse 结构体中嵌入了Interface接口
type reverse struct {Interface
}

2.4、类型断言

        类型断言就像 Java 中的强转一样,一般是把一个抽象的接口类型转为一个确定的实现类型。好像说我们可以"断言"这个接口类型一定是这个实现类类型。

2.4.1、语法

x.(T)
  • x:表示接口类型的变量(如果不是接口类型的就在前面加上空接口)
  • T:表示断言 x 是 T 类型

注意:类型断言的返回结果是两个参数,第一个返回值是一个转为断言类型后的变量,第二个返回值是转为断言的结果(布尔类型,代表成功/失败)

        对于数值类型( 比如 int、string、float64... )这些不是接口类型的数据,如果要做类型断言就需要给它前面加个空接口,因为所有类型都是隐式地实现了空接口的。

    str := "10"// 第2个返回值是断言结果res,_ := interface{}(str).(int)fmt.Println(res) // 10

        对于接口类型变量,如果我们能知道它是哪个实现类型就可以直接进行类型断言:

    ​​var usb USB = Mouse{name: "外星人"}// 类型断言 这里没有接收第二个返回值,代表丢弃m := usb.(Mouse)fmt.Println(m)

        上面的 USB 是接口类型,而它的地址指向一个 Mouse 类型的实例,所以我们可以断言这个 USB 实例一定是 Mouse 类型。

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

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

相关文章

在ADS中进行稳定性分析的严格方法-使用返回差与策动点阻抗

在ADS中进行稳定性分析的严格方法-使用返回差与策动点阻抗 在ADS中进行稳定性分析&#xff08;以避免K稳定性因子的局限性&#xff09;-理论部分中介绍了奈奎斯特图的基本原理和判定方法&#xff0c;并在ADS中举例稳定和不稳定的例子。 在在ADS中进行稳定性分析的多种理论方法…

基于SpringBoot的“在线BLOG网”的设计与实现(源码+数据库+文档+PPT)

基于SpringBoot的“在线BLOG网”的设计与实现&#xff08;源码数据库文档PPT) 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBoot 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 在线BLOG网结构功能图 管理员登录功能界面 用户信息…

mysql binlog入门

binlog 什么是binlog binlg记录了所有的表结构变更&#xff08;CREATE、ALTER TABLE…&#xff09;以及表数据修改&#xff08;INSERT、UPDATE、DELETE…&#xff09;&#xff0c;以事件形式记录&#xff0c;还包含语句所执行的消耗的时间。 简单的说就是&#xff0c;只要对…

call 和 apply

call() 和 apply() 方法在功能上是类似的&#xff0c;它们都用于调用函数并指定函数执行时的上下文&#xff08;即 this 的值&#xff09;&#xff0c;但它们的参数传递方式略有不同&#xff1a; call() 方法&#xff1a;接受一个参数列表&#xff0c;第一个参数是要绑定给函数…

Java Spring 中的声明式事务管理

Spring框架中的声明式事务管理是一种非编程式的事务管理方式&#xff0c;它允许开发者通过配置而非编程的方式来管理事务。这种方式使得事务管理与业务逻辑解耦&#xff0c;提高了代码的可读性和可维护性。 在Spring中&#xff0c;声明式事务管理主要依赖于AOP&#xff08;面向…

Grafana 添加一台管理服务器

1、修改prometheus.yml 添加新服务器信息 2、重启pro 3、导入node文件 4、启动node 5、检验数据

大话人工智能之训练数据集

1.训练集(Training Set) 用于训练模型的数据集。训练集用来训练模型&#xff0c;拟合出数据分布规律&#xff0c;即确定模型的权重和偏置等参数&#xff0c;这些参数称为学习参数。 训练集使用多次确定模型权重、偏置等学习参数训练出&#xff08;学习出&#xff09;模型通常情…

拓云启航 移动云全网型经销渠道合作伙伴火热招募

2024年4月28日至29日&#xff0c;2024中国移动算力网络大会在苏州召开。28 日下午大会主论坛现场&#xff0c;中国移动发布移动云全新万象算力网络生态合作计划&#xff0c;加速算力网络新质生产力落地。后续&#xff0c;移动云将依托“拓云计划”&#xff0c;招募超万家渠道伙…

华为配置mDNS网关示例(AP与AC间二层转发)

华为配置mDNS网关示例&#xff08;AP与AC间二层转发&#xff09; 组网图形 图1 配置mDNS网关组网图 组网需求配置思路操作步骤配置文件 组网需求 如图1所示&#xff0c;某企业的移动终端通过WLAN连接网络&#xff0c;AP_1和AP_2分别与AC之间采用二层转发。部门1和部门2分别属…

用Python Turtle画一个中国结

中国结&#xff0c;作为中华民族传统文化的象征之一&#xff0c;以其独特的编织技艺和深厚的文化内涵&#xff0c;深受人们喜爱。今天&#xff0c;我们就来用Python的turtle模块&#xff0c;尝试绘制一个充满韵味的中国结。 我们先来看看整个中国结生成的过程&#xff1a; 中国…

2024年,如何实现高效的自动化渗透测试?

随着当前网络安全威胁的不断扩展与升级&#xff0c;开展渗透测试工作已经成为广大企业组织主动识别安全漏洞与潜在风险的关键过程。然而&#xff0c;传统的人工渗透测试模式对测试人员的专业能力和经验水平有很高的要求&#xff0c;企业需要投入较大的时间和资源才能完成。在此…

springboot3使用spring-boot-maven-plugin插件打包后找不到主类问题

打包后的jar很小只有几十K 修改plugin为以下内容 <plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><executions><execution><goals><goal>repackage</goal&…

linux jmeter ant下载并安装【2024-亲测】

环境 centos7 一、下载jmeter 在这里插入代码片wget https://dlcdn.apache.org//jmeter/binaries/apache-jmeter-5.6.3.tgz --no-check-certificate解压 tar -zxvf apache-jmeter-5.6.3.tgz复制到安装目录、设置环境变量 vim /etc/profile添加环境变量&#xff0c;路径改成…

监控操作台为生活提供安全保障

在科技日新月异的现代社会&#xff0c;监控操作台已成为我们生活中不能缺少的一部分。它犹如一座城市的守护神&#xff0c;默默无闻地守护着我们的安全&#xff0c;确保着每一刻的平安。今天&#xff0c;和北京嘉德立一同走进这个神秘的世界&#xff0c;揭开监控操作台的神秘面…

中国智造再升级,基点生物全球首发新一代高端自动化实验室冰箱

生物低温存储领域中国智造再次取得重要突破。近日&#xff0c;基点生物在第十六届中国整合生物样本学大会和2024国际生物及环境样本库协会年会&#xff08;ISBER 2024&#xff09;上&#xff0c;正式发布了最新一代高端实验室冰箱&#xff0c;这一创新设备的发布&#xff0c;标…

三种修改 Docker 镜像默认存储位置的方法

由于系统初始分区的原因&#xff0c;导致操作系统中对应 / 分区不会太大&#xff0c;通过 /var 目录不会单独分区。如果上面运行 Docker 服务&#xff0c;经过长时间的使用&#xff0c;会使原本就比较大的分区越来越不够用。如何更好地的处理这个问题呢&#xff1f; 1. 使用软…

ai口语软件有合适的吗?分享4款!

在全球化日益深入的今天&#xff0c;英语作为国际通用语言&#xff0c;其重要性不言而喻。然而&#xff0c;传统的英语学习方式往往枯燥无味&#xff0c;难以持续。幸运的是&#xff0c;随着人工智能技术的快速发展&#xff0c;AI英语口语软件应运而生&#xff0c;为语言学习者…

C#-FTP帮助类相关操作的简单封装

目录 1、Ftp帮助类的框架封装 2、初始化Ftp连接 3、检查Ftp连接 4、Ftp文件上传 5、Ftp文件下载 6、获取Ftp上文件/文件夹列表 7、删除Ftp文件 8、删除Ftp文件夹 9、创建Ftp文件夹 10、更改Ftp文件名 11、获取Ftp文件大小 1、Ftp帮助类的框架封装 public class FtpH…

中应该如何让c++工程认识.c工程编译出来的库文件?

from gpt 但是 测试此方法没问题 在 .h 文件中声明 C 函数的原型是让 C 工程认识 C 工程编译出来的库文件的关键。下面是一种常见的做法&#xff1a; 在 .h 文件中声明函数原型&#xff1a; 创建一个 .h 文件&#xff0c;其中包含要在 C 代码中调用的 C 函数的声明。这些声明…

IT外包:打通企业和IT技术人才之间的障碍

近年来&#xff0c;随着互联网信息的快速发展&#xff0c;各种企业之间的信息竞争越来越激烈&#xff0c;越来越多的企业对IT人才的需求逐渐增加。很多企业经常感叹每年都在招人&#xff0c;然而每年都不靠谱。一方面要谨慎&#xff0c;担心请神容易送神难。另一方面&#xff0…