go语言基础 -- 面向对象 -- 接口与多态

接口定义与基本使用 - interface

go语言中,接口类型可以定义一组方法,不需要在接口定义中实现方法,并且interface中不能含有变量,如果某个自定义类型要使用时再实现接口的方法。
golang中的接口不需要显式地实现,只要一个类型实现了接口所有的方法,那么这个类型就实现了这个接口
接口的声明与实现

package main
import (
    "fmt"
)
// 声明一个接口
type Usb interface {
    // 声明两个没有实现的方法
    Start()
    Stop()
}

type Phone struct {

}
// 让Phone实现Usb接口的方法
// 实现一个接口,就是实现接口的所有方法
func (p Phone) Start() {
    fmt.Println("phone start")
}
func (p Phone) Stop() {
    fmt.Println("phone stop"))
}

type Camera struct {

}
func (c Camera) Start() {
    fmt.Println("camera start")
}
func (c Camera) Stop() {
    fmt.Println("camera stop")
}

type Computer {

}
// Working接收一个Usb接口的参数
func (c Computer) Working(usb Usb) {
    usb.start()
    usb.stop()
}
func main() {
    computer := Computer{}
    phone := Phone{}
    camera := Camera{}
    // 调用phone的方法
    computer.Working(phone)
    // 调用camera的方法
    computer.Working(camera)
}

接口应用场景

定义好接口后,可方便地分配好各个接口的实现工作

接口使用的注意事项

  1. 接口不能用来创建对象,但可以用来指向一个实现了该接口的对象
type Student struct{
    Name string
}
type A interface {
    Say()
}
func (stu Student) Say() {
    fmt.Println(stu.Name)
}
func main() {
    stu := Student{"John"}
    // 可以用接口指向一个定义好的对象,然后用接口调用对象的方法
    a A = stu
    a.Say()
}
  1. 只要是自定义类型,都可以实现接口
  2. 一个自定义类型可以实现多个接口。如果将一个类型变量赋值给不同的接口,那么就能使用不同的接口来调用该类型的方法。
  3. 一个接口可以继承自其他多个接口,这时如果要实现该接口,需要实现其继承的所有接口,继承的方式也类似结构体的继承,定义匿名接口即可,下例:
type Ai interface {
    SayA()
}
type Bi interface {
    SayB()
}
type Ci interface {
    Ai
    Bi
    SayC()
}
  1. interface类型默认是指针,如果没初始化就使用,会输出nil
  2. 空接口没有实现任何方法,所有类型都实现了空接口,我们可以把任意类型(包括基础数据类型)的变量赋值给空接口;
type T interface{
}
func main() {
    var stu Student
    var t T = stu
}
  1. 接口的继承不允许出现相同的方法名
  2. 在将变量赋值给接口时,严格区分指针类型和值类型
type Cap interface{
    Say()
}
type Stu struct{
}
func (this *Stu) Say() {
    fmt.Println("stu say")
}
func main() {
    var stu Stu = Stu{}
    cap interface = &stu // 这里不能写成stu
}

接口的最佳实践案例

实现对hero结构体切片的排序,我们可以用官方库里面的Sort函数,这个函数接收Interface参数,只需要实现Interface的三个方法,即可对对应的接口变量进行排序:
在这里插入图片描述

package main
import(
    "fmt"
    "sort"
)

type Hero struct {
    Name string
    Age int
}
// 声明一个Hero切片类型
type HeroSlice []Hero
// 实现Interface的三个方法
func (hs HeroSlice) Len() int {
    return len(hs)
}
// 若i下标变量大于j下标变量成立被返回,则降序,否则升序
func (hs HeroSlice) Less(i int, j int) bool {
    return hs[i].Age > hs[j].Age
}
func (hs HeroSlice) Swap(i, j int) {
    //temp := hs[i]
    //hs[i] = hs[j]
    //hs[j] = temp
    // go中可以直接这样写交换
    hs[i], hs[j] = hs[j], hs[i]
}
func main() {
    var heros = HeroSlice
    // 初始化heros...
    // 排序
    sort.Sort(heros)
}

接口与继承的对比总结

  1. 当我们不想破坏继承关系,但想对某个自定义类型扩展功能,那么就可以通过接口来实现,实现接口可以看做对继承的一种补充
  2. 当两个不同的结构体需要实现同样的方法的时候,用接口比在原结构体上分别实现方法会更加灵活
  3. 继承的价值更多在于复用和可维护,接口的价值在于规范设计,至于规范实现可交由其他自定义类型实现

go语言中的多态

所谓多态,指的是变量的多种形态,像c/c++语言中允许父类的指针指向子类的对象,在go里面,多态是通过接口来实现的,通过统一的接口来调用不同的实现,接口变量就呈现了多种形态。如Usb接口,可以接收手机变量和相机变量,就体现了usb接口的多态特征(根据传入的变量具体类型来决定调用什么方法)

接口的多态体现

  1. 多态参数,也即同一个接口作为参数,但可以根据具体传入的变量类型来决定使用的方法
  2. 多态数组,如定义一个Usb接口,可以存放phone结构体对象和Camera结构体对象,这就允许数组存放多种类型。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

秘密共享差分隐私原理解析

1. 隐私计算全貌  可以看到,隐私计算技术从1979年就开始了,历经四代从安全多方计算(MPC)、到差分隐私(DP)、到集中加密技术(TEE),再到联邦学习(FL)。 2. 秘密共享 secret Sharing 就是“秘密分享”或者“秘密共享”…

“互动+消费”时代,借助华为云GaussDB重构新零售中消费逻辑

场与人的关系 “人—货—场”是零售中重要的三要素,我们一直在追求,将零售中的人、货、场进行数字化并在云端进行整合,形成属于我们自己的云平台。 随着互联网技术为信息提供的便利,消费者的集体力量正在逐渐形成一股强大的反向…

Applied Energy+C论文复现:考虑泊位分配灵活性的港口综合能源系统优化调度程序代码!

程序结合了港口独特的工作属性,构建了泊位优化分配的模型,提出了考虑泊位优化和多能协同的港口综合能源运行优化模型。港口运营商根据多种能源供应的成本特性决策船舶停泊的开始/结束时间,改变港口的总负荷需求曲线。程序算例丰富…

使用postman测试若依登录接口API-2

请求方式 由于登录控制器可知:该请求方式为Post请求 请求地址 在请求路径栏输入请求地址,如下图所示: 参数体 在Body键入所需参数,类型选择raw,数据格式选择"JSON":如下图所示: 认证成功与失败…

特征值和特征向量及其在机器学习中的应用

特征值和特征向量是线性代数中的概念,用于分析和理解线性变换,特别是由方阵表示的线性变换。它们被用于许多不同的数学领域,包括机器学习和人工智能。 在机器学习中,特征值和特征向量用于表示数据、对数据执行操作以及训练机器学…

NOIP 2009普及组初赛试题及解析

NOIP 2009普及组初赛试题及解析 一. 单项选择题 (共20题,每题1.5分,共计30分。每题有且仅有一个正确答案.)。二. 问题求解(共2题,每题5分,共计10分)三. 阅读程序写结果(共…

Vue.js 深度解析:模板编译原理与过程

🤍 前端开发工程师、技术日更博主、已过CET6 🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 🍚 蓝桥云课签约作者、上架课程《Vue.js 和 E…

网络学习:SMart link技术与Monitor link技术

目录 一、SMart link技术 1.1、SMart link技术简介 1.2、SMart link技术原理及基础知识点 1、应用场景(举例): 2、运行机制 3、保护vlan 4、控制VLAN 5、Flush报文 6、SMart link的负载分担机制 7、SMart link角色抢占模式 二、Mo…

YOLOv5目标检测学习(1):yolo系列算法的基础概念

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、基于深度学习的目标检测需要哪些步骤?二、数据准备(即准备数据集)1.目标检测的数据集如何获取?2.数据集包括…

Python报错ModuleNotFoundError: No module named ‘numpy‘

原因:缺少“numpy” 进入python安装路径,script路径内 在路径下启动终端 01.更新numpy python -m pip install --upgrade pip 02.安装 pip install numpy 03.运行python python 04.导入包 from numpy import * 问题已解决。

MySQL学习Day25——数据库其他调优策略

一、数据库调优的措施: 1.调优的目标: (1)尽可能节省系统资源,以便系统可以提供更大负荷的服务 (2)合理的结构设计和参数调整,以提高用户操作的响应速度 (3)减少系统的瓶颈,提高MySQL数据库整体的性能; 2.如何定位调优:用户的反馈、日志…

政安晨【TypeScript高级用法】(二):泛型与命名空间

TypeScript的泛型允许我们在定义函数、类和接口时使用参数化类型,使得这些实体可以适应不同类型的数据。泛型可以增加代码的重用性和灵活性。 同时,TypeScript的命名空间提供了一种在全局命名空间中组织代码的方式,可以避免全局变量污染和命…

项目打包时报错 There are test failures.

报错原因是 test测试类有问题 我们可直接选择跳过测试类打包 如下 此时再次打包就成功了

高级软件开发知识点

流程 算法题简历上项目用到技术、流程、遇到问题HR 准备 常考的题型和回答思路刷100算法题,理解其思想,不要死记最近一家公司所负责的业务和项目: 项目背景、演进之路,有哪个阶段,每个阶段主要做什么项目中技术选型…

vue2和vue3的区别介绍

Vue.js 是一个流行的前端JavaScript框架,用于构建用户界面和单页应用程序。自从Vue.js首次发布以来,它就因其简洁的API、灵活的架构和易于上手的特点而受到了广泛的欢迎。Vue.js的第二个主要版本(Vue 2)发布于2016年,而…

AutoGPT实现原理

AutoGPT是一种利用GPT-4模型的自动化任务处理系统,其主要特点包括任务分配、多模型协作、互联网访问和文件读写能力以及上下文联动记忆性。其核心思想是通过零样本学习(Zero Shot Learning)让GPT-4理解人类设定的角色和目标,并通过…

正则表达式在QT开发中的应用

一.正则表达式在QT开发中的使用: 1.模式匹配与验证:正则表达式最基本的作用就是进行模式匹配,它可以用来查找、识别或验证一个字符串是否符合某个特定的模式。例如,在表单验证中,可以使用正则表达式来检查用户输入的邮…

微擎安装,卡在“安装微擎”界面

进入install.php,点击【在线安装】 下一步配置数据库,开始安装系统 然后显示进度条,进度条一闪而过 然后就没有进度条显示了,一直卡在这里 第一次等了好久, 删除目录下的文件,重装还是这样 再重启服务器&…

C语言数组作为函数参数

有两种情形; 一种是数组元素作为函数实参;一种是数组名作为函数参数; 新建一个VC6单文档工程; void printshz(int , CDC* , int , int ); double getav(int a[5]); ...... void CShzcshView::OnDraw(CDC* pDC) {CShzcshDoc* pDo…

electron+vue3全家桶+vite项目搭建【29】封装窗口工具类【3】控制窗口定向移动

文章目录 引入实现效果思路声明通用的定位对象主进程模块渲染进程测试效果 引入 demo项目地址 窗口工具类系列文章: 封装窗口工具类【1】雏形 封装窗口工具类【2】窗口组,维护窗口关系 封装窗口工具类【3】控制窗口定向移动 很多时候,我们想…