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

news2024/12/27 12:08:52

1、OOP

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

1.1、封装

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

1.2、继承

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

1.2.1、嵌套匿名字段

//Address 地址结构体
type Address struct {
	Province string
	City     string
}

//User 用户结构体
type User struct {
	Name    string
	Gender  string
	Address //匿名字段
}

func main() {
	var user2 User
	user2.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 string
	City     string
}

//User 用户结构体
type User struct {
	Name    string
	Gender  string
	Address 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 main

import "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.go

type 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 {
	Reader
	Writer
}

// ReadCloser 是组合Reader接口和Closer接口形成的新接口类型
type ReadCloser interface {
	Reader
	Closer
}

// WriteCloser 是组合Writer接口和Closer接口形成的新接口类型
type WriteCloser interface {
	Writer
	Closer
}

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

// src/sort/sort.go

// Interface 定义通过索引对元素排序的接口类型
type Interface interface {
    Len() int
    Less(i, j int) bool
    Swap(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.coloradmin.cn/o/1640743.html

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

相关文章

ue引擎游戏开发笔记(28)——实现第三人称越肩视角

1.需求分析 实现一个第三人称越肩视角 2.操作实现 1.思路&#xff1a;建立一个弹簧臂和摄像机&#xff0c;调整两者位置达到越肩效果。 2.直接在蓝图操作&#xff1a;添加摄像机和弹簧臂&#xff1a; 3.对弹簧臂勾选使用pawn控制旋转&#xff0c;并适当调整摄像机和弹簧臂位置…

QT:输入类控件的使用

LineEdit 录入个人信息 #include "widget.h" #include "ui_widget.h" #include <QDebug> #include <QString>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);// 初始化输入框ui->lineEdit…

电脑崩溃了,之前备份的GHO文件怎么恢复到新硬盘?

前言 之前咱们说到用WinPE系统给电脑做一个GHO镜像备份&#xff0c;这个备份可以用于硬盘完全崩溃换盘的情况下使用。 那么这个GHO镜像文件怎么用呢&#xff1f; 咱们今天详细来讲讲&#xff01; 如果你的电脑系统硬盘崩溃了或者是坏掉了&#xff0c;那么就需要使用之前备份…

Git的基本操作和使用

git分支指令 列出所有本地分支 git branchmaster是绿的 前面有个 表示当前分支是master* 列出所有远程分支 git branch -r列出所有本地分支和远程分支 git branch -a新建一个分支&#xff0c;但依然停留在当前分支 git branch [branch-name]新建一个分支&#xff0c;并切…

Redis__三大日志

文章目录 &#x1f60a; 作者&#xff1a;Lion J &#x1f496; 主页&#xff1a; https://blog.csdn.net/weixin_69252724 &#x1f389; 主题&#xff1a;Redis__三大日志 ⏱️ 创作时间&#xff1a;2024年04月30日 ———————————————— 对于MySQL来说, 有…

政安晨:【Keras机器学习示例演绎】(三十)—— 使用变换器进行视频分类

目录 数据收集 设置 定义超参数 数据准备 构建基于变换器的模型 培训的效用函数 模型训练和推理 政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 收录专栏: TensorFlow与Keras机器学习实战 希望政安晨的博客能够对您有所裨益&#xff0c;如有不…

C语言/数据结构——每日一题(环形链表的约瑟夫问题)

一.前言 今天在牛客网上面看到了一道环形链表题&#xff0c;想着和大家们分享一下。可能我有点笨&#xff0c;那道题的链接我没搞好&#xff0c;所以很抱歉&#xff0c;只能麻烦大家们看一下截屏的题目信息了。废话不多数&#xff0c;让我们开始今天的题目分享吧。 二.正文 …

论文笔记(四十五)Attention Is All You Need

Attention Is All You Need 文章概括摘要1. 介绍2. 背景3. 模型架构3.1 编码器和解码器堆栈3.2 Attention3.2.1 按比例点积Attention3.2.2 Multi-Head Attention3.2.3 注意力在模型中的应用 3.3 定位前馈网络3.4 嵌入与 Softmax3.5 位置编码 4 为什么 Self-Attention5. Trainin…

手撕vector的模拟实现

&#x1d649;&#x1d65e;&#x1d658;&#x1d65a;!!&#x1f44f;&#x1f3fb;‧✧̣̥̇‧✦&#x1f44f;&#x1f3fb;‧✧̣̥̇‧✦ &#x1f44f;&#x1f3fb;‧✧̣̥̇:Solitary_walk ⸝⋆ ━━━┓ - 个性标签 - &#xff1a;来于“云”的“羽球人”。…

Python梯度提升决策树库之lightgbm使用详解

概要 LightGBM是一个快速、分布式、高性能的梯度提升决策树(Gradient Boosting Decision Tree)库,它在机器学习和数据挖掘领域被广泛应用。本文将介绍LightGBM库的安装方法、主要特性、基本功能、高级功能、以及在实际应用中的场景和总结。 安装 首先,需要安装LightGBM库…

【doghead】ubuntu构建libuv

按照官方的文档2024年3月的版本。首先构建libuv 最终构建的还得了test 构建过程 zhangbin@DESKTOP-1723CM1:/mnt/d/XTRANS/thunderbolt/ayame/zhb-bifrost$ ls Bifrost-202403 README.md draw player-only worker 大神的带宽估计.png zhangbin@DESKTOP-1723CM1:/mnt/d/XTRANS/…

python学习笔记B-20:序列实战--处理千年虫

将2位数表达的年份&#xff0c;转换为用4位数表达&#xff1a; print("将列表中的2位数年份转换为4位数年份") lst[88,89,90,00,99] print(lst) for index in range(len(lst)):if len(str(lst[index]))2:lst[index] 1900int(lst[index])elif len(str(lst[index]))1…

AI学习指南-人工智能概述

欢迎来到人工智能的奇妙世界&#xff01;如果你是初学者&#xff0c;那么你来对地方了。今天&#xff0c;我们将一起探索人工智能&#xff08;AI&#xff09;的基本概念&#xff0c;看看它是如何分类的&#xff0c;它的应用有哪些&#xff0c;以及未来可能的发展方向。准备好了…

7个策略,让你的可视化大屏打动人心!

要打动人心的可视化大屏&#xff0c;可以采取以下策略&#xff1a; 引人入目的设计&#xff1a; 选择鲜明而吸引人的颜色和视觉效果&#xff0c;使用引人注目的动画和过渡效果&#xff0c;以及吸引眼球的图形和图案设计。通过精心设计的布局和排版&#xff0c;确保信息清晰可…

vivado Aurora 8B/10B IP核(9)- CRC、 Aurora 8B/10B内核的时钟接口端口

CRC 模块提供 16 位或 32 位 CRC&#xff0c;用于用户数据。 Aurora 8B/10B 内核的时钟接口端口 从相邻收发器四边形的时钟Xilinx 实现工具可以根据需要对南北路由和引脚交换到收发器时钟输入进行必要的调整&#xff0c;以将时钟从一个四线到另一个。 重要信息&#xff1a;共…

HTML5实用大全(Part.2)

引言&#xff1a; 哈喽&#xff0c;各位小伙伴们大家好呀&#xff0c;学习了上一篇关于HTML5的文章后&#xff0c;你是否对于入门HTML5有了一定的基础了呢&#xff0c;本篇博客我们将继续学习HTML5的不同标签&#xff0c;跟上队伍&#xff0c;准备出发咯&#xff01; 1.标签之…

RMQ从入门到精通

一.概述与安装 //RabbitMQ //1.核心部分-高级部分-集群部分 //2.什么是MQ 消息队列message queue 先入先出原则;消息通信服务 //3.MQ的大三功能 流量消峰 应用解耦 消息中间件 //&#xff08;1&#xff09;人-订单系统(1万次/S)—> 人 - MQ(流量消峰,对访问人员进行排队) -…

Qt_介绍_环境安装_创建新项目_实现helloworld_坐标_1

文章目录 一、Qt是什么二、Qt的发展史三、Qt支持的平台四、Qt版本五、Qt的优点六、Qt的应用场景七、Qt开发环境&#xff0c;需要按照3个部分1.C编译器&#xff08;gcc,cl.exe....不是Visual Studio&#xff09;2.Qt SDK3.需要有一个Qt的集成开发环境&#xff08;IDE&#xff09…

云服务器+ASF实现全天挂卡挂时长

目录 前言正文1.安装下载2.编辑配置文件3.设置Steam社区证书4.启动ASF5.给游戏挂时长6.进阶-ASF自动启动且后台保活 前言 我遇到的最大的问题是&#xff0c;网络问题 其实不然&#xff0c;各大厂商的云服务器后台都有流量监控&#xff0c;意味着依靠一般方法是不能正常访问St…

最新可商用级chatgpt4.0系统源码+Midjourney-AI绘画系统 集成国内外数十个AI大模型和绘画接口

随着科技的飞速发展&#xff0c;人工智能正在逐步改变我们的生活&#xff0c;特别是在艺术创作领域。分享一款最新可商用级ChatGPT 4.0系统源码与Midjourney AI绘画系统的完美结合&#xff0c;集成国内外数十个AI大模型与绘画接口&#xff0c;为创作者们带来了前所未有的智能创…