Go——面向对象

news2024/11/25 8:23:29

一. 匿名字段

        go支持只提供类型而不写字段名的方式,也就是匿名字段,也称为嵌入字段。

  • 同名字段的情况

  • 所以自定义类型和内置类型都可以作为匿名字段使用

  • 指针类型匿名字段

二.接口

        接口定义了一个对象的行为规范,但是定义规范不实现,由具体的对象实现规范的细节。

        2.1 接口类型

        在Go语言中接口(interface)是一种类型,一种抽象类型。

        interface是一组method的集合,接口做的事情就像定义一个协议,不关心属性(数据),只关心行为(方法)。

        2.2 为什么使用接口

        查看下面的图片,只是由于类型不同,就需要定义两个逻辑一样的函数。如果后面出现了其它动物,也会需要定义函数。

        Go语言为了解决类似上面的问题,就设计了接口这个概念。接口区别于我们之前所有的具体类型,接口是一个抽象类型。当你看到一个接口类型是,你不知道他是什么,唯一知道的是通过它的方法能做什么。 

        2.3 接口定义

        Go语言提倡面向接口编程。

  • 接口在底层实现上包含两部分,即类型(type)和数据(data)。
  • 接口是一个或多个方法签名的集合
  • 任何类型的方法集中只要拥有该接口对应的全部方法,就表示它实现了该接口,无须在该类型上显示声明实现了那个接口。这称为Structural Typing。
  • 所谓对应方法,是指有相同名称,参数列表(不包括参数名)以及返回值。
  • 当然,该类型还可以有其它方法。
  • 接口只有方法声明,没有实现,没有数据字段(属性)
  • 接口可以匿名嵌入其它接口,或者嵌入到其它结构中。
  • 对象赋值给接口时,会发生拷贝,而接口内部存储的是指向这个复制品的指针,即无法修改复制品的状态,也无法获取指针。即如果对象是结构体或者基本数据类型,它会被值拷贝到接口中。如果对象是指针类型,这个指针指向的结构体实现了接口,那么接口中存储的是指针的副本,而不是指针本身。
  • 只有当接口存储的类型和对象都为nil时,接口才为nil。
  • 接口调用不会做receiver的自动转换。
  • 接口同样支持匿名字段方法。
  • 接口可以实现类似面向对象编程(OOP)的多态。
  • 空接口可以作为任何类型数据的容器。空接口是没有声明任何方法的接口。但是,也无法通过空接口来调用对象的方法或访问其属性。
  • 一个类型可以实现多个接口。
  • 接口命名习惯以er结尾。

        每一个接口由数个方法组成,接口的定义格式如下:

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

        其中:

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

        举个例子:

type writer interface{
    Write([]byte) error
}

        当看到这个接口的时候,你不知道他是什么,唯一知道的是可以通过它的Write方法来做一些事情。

        2.4 实现接口的条件

        一个对象只要全部实现了接口的方法,那么就实现了这个接口。换句话说,接口就是一个需要实现的方法列表。

package main

import "fmt"

type Sayer interface {
	Say()
}

type Cat struct{}

//实现了Sayer接口
func (c *Cat) Say() {
	fmt.Println("喵喵喵...")
}

type Dog struct{}

//实现了Sayer接口
func (d *Dog) Say() {
	fmt.Println("汪汪汪...")
}

        2.5 接口类型变量

        接口类型变量能够存储所有实现了该接口的实例。

        需要指针传入是因为方法的receiver为指针类型,对象的指针类型(*T)的方法集为值类型(T)和指针类型(*T)。

        2.6 值接收者和指针接收者实现接口的区别

        值接收者和指针接收者实现接口区别在于:方法集的不同。接口接收值类型(T)对象方法集为值接收者(T)实现的方法。接口接收指针类型对象(*T)方法集为值接收者(T)和指针接收者(*T)现象的方法。

  • 值接收者

  •  指针接收者

        2.7 类型与接口的关系

        2.7.1 一个类型实现多个接口

        一个类型可以同时实现多个接口,而接口间彼此独立,不知道对方的实现。

                2.7.2 多个类型实现同一个接口

        Go语言中不同的类型还可以实现同一接口。

        一个接口的方法不一定需要由一个类型完全实现,接口的方法可以通过在类型中嵌入其它类型或者结构体来实现。

        2.7.3 接口嵌套

         接口与接口之间可以通过嵌套创造出新的接口。

type Sayer interface {
	Say()
}

type Mover interface {
	Move()
}

type Animal interface {
	Sayer
	Mover
}

        嵌套的接口的使用和普通接口一样,这里实现嵌套的接口。

        2.8 空接口

        2.8.1 空接口的定义

        空接口是指没有定义任何方法的接口。因此任何类型都实现了空接口。

        空接口类型变量可以存储任意类型的变量。

        2.8.2 空接口的应用

  • 空接口作为函数参数

        使用空接口实现可以接收任意类型的函数参数。

  • 空接口作为map的值

        使用空接口实现可以保存任意值的字典。

         2.8.3 类型断言

        空接口可以存储任意类型的值,那我们如何获取其存储的具体数据呢?

  • 接口值

        一个接口的值(简称接口值)是由一个具体类型和具体类型的值俩个部分组成。这两部分分别称为接口的动态类型和动态值。

        我们来看一个例子:

package main

import (
	"bytes"
	"io"
	"os"
)

func main() {

	var w io.Writer
	w = os.Stdout
	w = new(bytes.Buffer)
	w = nil
}

        图解: 

        想要判断空接口中的值这个时候就可以使用类型断言,其语法格式:

x.(T)

        其中:

  • x:表示类型为interface{}的变量
  • T :表示断言x可能是的类型

        该语法返回两个参数,第一个参数是x转化为T类型后的变量,第二个是布尔值,若为true表示断言成功,为false则表示断言失败。

        举个例子:

        自定义类型: 

        我们还可以使用switch语句来实现多个类型的断言:

        因为空接口可以存储任意类型值的特点,所以空接口在Go语言中使用十分广泛。

         但是接口需要注意的是,只有当有两个或者两个以上的具体类型必须以相同的方式进行处理时才需要定义接口。不要为了接口而写接口,那样会增加不必要的抽象,导致不必要的运行时消耗。

 

 

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

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

相关文章

MT3022 召唤神龙

思路&#xff1a;二分答案 。check():检查组p套卡是否成立&#xff0c;即检查r卡是否足够组成p套卡。 &#xff08;易错点&#xff1a;check的思路&#xff0c;开long long&#xff09; #include <bits/stdc.h> using namespace std; long long int n, m; long long int…

JavaScript逆向爬取实战——使用Python实现列表页内容爬取

JavaScript逆向爬取—使用Python实现列表页内容爬取 1. 案例介绍 案例网址&#xff1a;https://spa6.scrape.center/&#xff0c; 如图所示&#xff1a; 点击任意一步电影&#xff0c;观察一下URL的变化&#xff0c;如图所示&#xff1a; 看到详情页URL包含了一个长字符串&am…

力扣HOT100 - 189. 轮转数组

解题思路&#xff1a; 三次反转。 先反转一次&#xff0c;再根据 k 拆分成两部分各反转一次。 class Solution {public void rotate(int[] nums, int k) {k % nums.length;reverse(nums, 0, nums.length - 1);reverse(nums, 0, k - 1);reverse(nums, k, nums.length - 1);}pu…

使用Docker中构建Java jar包,并且实现开启自启

文章目录 1.创建Dockerfile2.构建Docker镜像3.运行Docker容器4.后台运行并且可以开机自启4.1 在后台运行Docker容器4.2 设置开机自启动容器4.3 在Docker守护程序启动时自动启动容器 Docker中构建Java JAR包 要在Docker容器中构建Java应用程序的JAR包&#xff0c;你可以遵循以下…

RISC-V GNU Toolchain 工具链安装问题解决(stdio.h 问题解决,pk fence.i 问题解决)

我的安装过程主要参照 riscv-collab/riscv-gnu-toolchain 的官方 Readme 和这位佬的博客&#xff1a;RSIC-V工具链介绍及其安装教程 - 风正豪 &#xff08;大佬的博客写的非常详细&#xff0c;唯一不足就是 sudo make linux -jxx 是全部小写。&#xff09; 工具链前前后后我装了…

Docker容器嵌入式开发:在Ubuntu上配置Postman和flatpak

在 Ubuntu 上配置 Postman 可以通过 Snap 命令完成&#xff0c;以下是所有命令的总结&#xff1a; sudo snap install postmansudo snap install flatpak在 Ubuntu 上配置 Postman 和 Flatpak 非常简单。以下是一些简单的步骤&#xff1a; 配置 Flatpak 安装 Flatpak&#x…

【Redis】底层跳表实现

先巩固Redis的数据类型以及底层的数据结构&#xff1a; ZSet&#xff08;有序集合&#xff09;可以使用两种不同的内部数据结构来表示&#xff1a;压缩列表&#xff08;ziplist&#xff09;和跳跃表&#xff08;skiplist&#xff09;。 跳表是redis底层SortedSet(ZSet)的数据…

PostgreSQL入门到实战-第九弹

PostgreSQL入门到实战 PostgreSQL数据过滤(二)官网地址PostgreSQL概述PostgreSQL中and操作理论PostgreSQL中and操作实操更新计划 PostgreSQL数据过滤(二) 了解PostgreSQL AND逻辑运算符以及如何使用它来组合多个布尔表达式。 官网地址 声明: 由于操作系统, 版本更新等原因, …

uniapp中页面滚动锚点位置及滚动到对应高度显示对应按钮

可以把页面代码和组件代码放自己项目里跑一下 页面代码 <template><view class"Tracing-detail"><view class"title" v-for"i in 30">顶部信息</view><!-- tab按钮 --><Tab v-model"activeIndex" …

Golang | Leetcode Golang题解之第13题罗马数字转整数

题目&#xff1a; 题解&#xff1a; var symbolValues map[byte]int{I: 1, V: 5, X: 10, L: 50, C: 100, D: 500, M: 1000}func romanToInt(s string) (ans int) {n : len(s)for i : range s {value : symbolValues[s[i]]if i < n-1 && value < symbolValues[s…

信息流推广如何操作,需要从哪些方面入手?

信息流推广确实是一个涉及多方面细节的工作&#xff0c;需要我们从多个角度进行深入分析和操作。以下是我对信息流推广的一些理解和建议&#xff1a; 首先&#xff0c;明确投放平台是推广的起点。我们需要根据产品或服务的特点&#xff0c;选择适合的投放渠道&#xff0c;如短视…

利用DataX工具,实现MySQL与OceanBase的数据同步实践

数据迁移是经常遇到的需求&#xff0c;市面上为此提供了众多同步工具。这里将为大家简要介绍DataX的使用。DataX 是阿里云 DataWorks数据集成 的开源版本&#xff0c;它作为离线数据同步的工具/平台&#xff0c;在阿里巴巴集团内部被广泛应用。DataX 能够实现多种异构数据源之间…

什么是一站式知识库服务平台,它的作用是什么?

如今&#xff0c;对于企业来说&#xff0c;知识的获取、管理和共享变得越来越重要。一站式知识库服务平台也因此产生&#xff0c;它因为高效、便捷的特点&#xff0c;成为了多数企业和组织必不可少的使用工具。那么&#xff0c;什么是一站式知识库服务平台&#xff0c;它的作用…

【Linux】socket编程2

欢迎来到Cefler的博客&#x1f601; &#x1f54c;博客主页&#xff1a;折纸花满衣 &#x1f3e0;个人专栏&#xff1a;题目解析 目录 &#x1f449;&#x1f3fb;客户端代码Makefile(生成目标文件)UdpClient.cc(客户端代码)服务端代码部分优化1&#xff08;接受客户端时显示客…

基于达梦数据库开发-python篇

文章目录 前言一、搭建demo前提初始化简单demo 二、可能出现的异常情况DistutilsSetupErrorNo module named dmPythonlist报错 总结 前言 出于信创的考虑&#xff0c;近年来基于国产数据库达梦的应用开发逐渐变多。本文将介绍在windows环境下基于DM8版本的python的简单开发使用…

【机器学习300问】65、为什么Sigmoid和Tanh激活函数会导致梯度消失?

一、梯度消失现象 当神经网络的输入值较大或较小时&#xff0c;其导数&#xff08;梯度&#xff09;都会接近于0。在反向传播过程中&#xff0c;这些微小的梯度经过多层网络逐层传递时&#xff0c;会不断被乘以权重矩阵&#xff08;权重通常小于1&#xff09;&#xff0c;进一步…

2024人工智能与机器人系统国际学术会议(ICAIRS2024)

2024人工智能与机器人系统国际学术会议(ICAIRS2024) 会议简介 2024人工智能与机器人系统国际学术会议(ICAIRS2024)将在杭州举行。该会议旨在为人工智能和机器人系统的专家学者提供一个平台&#xff0c;以分享最新的研究成果、交流思想、探讨学术问题&#xff0c;并促进跨学科…

Open CASCADE学习|求曲面的参数空间

在三维空间中&#xff0c;任意的曲面都可以通过特定的方法映射到一个二维参数平面上&#xff0c;从而对其进行详细的几何分析和处理。首先&#xff0c;我们需要从三维模型中提取出特定的曲面&#xff0c;这通常被称为“Face”。一个face可以被视为三维空间中的一个封闭区域&…

【c++】c++线程库的基本使用

&#x1f4bb;文章目录 &#x1f4c4;前言C线程库创建线程互斥量mutexlock_guardunique_lock 同步机制condition_variableC20 信号量 的工作原理。 &#x1f4d3;总结 &#x1f4c4;前言 在C线程库推出之前&#xff0c;如果要实现跨平台多线程&#xff0c;那么我们就得需要直到…

Vue3报错:‘defineProps‘ is not defined no-undef

解决方法 在package.json中添加 "vue/setup-compiler-macros": true 记得在上面的 "node": true 后面加一个逗号 "eslintConfig": {"root": true,"env": {"node": true,"vue/setup-compiler-macros": t…