广告
返回顶部
首页 > 资讯 > 后端开发 > GO >浅谈Go语言多态的实现与interface使用
  • 456
分享到

浅谈Go语言多态的实现与interface使用

2024-04-02 19:04:59 456人浏览 安东尼
摘要

目录一、多态的含义二、抽象类与接口三、golang中的接口四、总结一、多态的含义 对于Java或者是c++而言,我们在使用变量的时候,变量的类型是明确的。但是如果我们希望它可以宽松一

一、多态的含义

对于Java或者是c++而言,我们在使用变量的时候,变量的类型是明确的。但是如果我们希望它可以宽松一点,比如说我们用父类指针或引用去调用方法,但是在执行的时候,能够根据子类的类型去执行子类当中的方法。也就是说实现我们用相同的调用方式调出不同结果或者是功能的情况,这种情况就叫做多态。

举个非常经典的例子,比如说猫、狗和人都是哺乳动物。这三个类都有一个say方法,大家都知道猫、狗以及人类的say是不一样的,猫可能是喵喵叫,狗是汪汪叫,人类则是说话。


class Mammal {
    public void say() {
    System.out.println("do nothing")
    }
}


class Cat extends Mammal{
    public void say() {
    System.out.println("meow");
    }
}


class Dog extends Mammal{
    public void say() {
    System.out.println("woof");
    }
}

class Human extends Mammal{
    public void say() {
    System.out.println("speak");
    }
}

这段代码大家应该都不难看懂,这三个类都是Mammal的子类,假设这个时候我们有一系列实例,它们都是Mammal的子类的实例,但是这三种类型都有,我们希望用一个循环来一起全都调用了。虽然我们接收变量的时候是用的Mammal的父类类型去接收的,但是我们调用的时候却会获得各个子类的运行结果。

比如这样:


class Main {
    public static void main(String[] args) {
        List<Mammal> mammals = new ArrayList<>();
        mammals.add(new Human());
        mammals.add(new Dog());
        mammals.add(new Cat());
        
        for (Mammal mammal : mammals) {
            mammal.say();
        }
    }
}

不知道大家有没有get到精髓,我们创建了一个父类的List,将它各个子类的实例放入了其中。然后通过了一个循环用父类对象来接收,并且调用了say方法。我们希望虽然我们用的是父类的引用来调用的方法,但是它可以自动根据子类的类型调用对应不同子类当中的方法。

也就是说我们得到的结果应该是:

speak

woof

meow

这种功能就是多态,说白了我们可以在父类当中定义方法,在子类当中创建不同的实现。但是在调用的时候依然还是用父类的引用去调用,编译器会自动替我们做好内部的映射和转化。

二、抽象类与接口

这样实现当然是可行的,但其实有一个小小的问题,就是Mammal类当中的say方法多余了。因为我们使用的只会是它的子类,并不会用到Mammal这个父类。所以我们没必要实现父类Mammal中的say方法,做一个标记,表示有这么一个方法,子类实现的时候需要实现它就可以了。

这就是抽象类和抽象方法的来源,我们可以把Mammal做成一个抽象类,声明say是一个抽象方法。抽象类是不能直接创建实例的,只能创建子类的实例,并且抽象方法也不用实现,只需要标记好参数和返回就行了。具体的实现都在子类当中进行。说白了抽象方法就是一个标记,告诉编译器凡是继承了这个类的子类必须要实现抽象方法,父类当中的方法不能调用。那抽象类就是含有抽象方法的类。

我们写出Mammal变成抽象类之后的代码:


abstract class Mammal {
    abstract void say();
}

很简单,因为我们只需要定义方法的参数就可以了,不需要实现方法的功能,方法的功能在子类当中实现。由于我们标记了say这个方法是一个抽象方法,凡是继承了Mammal的子类都必须要实现这个方法,否则一定会报错。

抽象类其实是一个擦边球,我们可以在抽象类中定义抽象的方法也就是只声明不实现,也可以在抽象类中实现具体的方法。在抽象类当中非抽象的方法子类的实例是可以直接调用的,和子类调用父类的普通方法一样。但假如我们不需要父类实现方法,我们提出提取出来的父类中的所有方法都是抽象的呢?针对这一种情况,Java当中还有一个概念叫做接口,也就是interface,本质上来说interface就是抽象类,只不过是只有抽象方法的抽象类。

所以刚才的Mammal也可以写成:


interface Mammal {
    void say();
}

把Mammal变成了interface之后,子类的实现没什么太大的差别,只不过将extends关键字换成了implements。另外,子类只能继承一个抽象类,但是可以实现多个接口。早先的Java版本当中,interface只能够定义方法和常量,在Java8以后的版本当中,我们也可以在接口当中实现一些默认方法和静态方法。

接口的好处是很明显的,我们可以用接口的实例来调用所有实现了这个接口的类。也就是说接口和它的实现是一种要宽泛许多的继承关系,大大增加了灵活性。

以上虽然全是Java的内容,但是讲的其实是面向对象的内容,如果没有学过Java的小伙伴可能看起来稍稍有一点点吃力,但总体来说问题不大,没必要细扣当中的语法细节,get到核心精髓就可以了。

讲这么一大段的目的是为了厘清面向对象当中的一些概念,以及接口的使用方法和理念,后面才是本文的重头戏,也就是Go语言当中接口的使用以及理念。

三、Golang中的接口

Golang当中也有接口,但是它的理念和使用方法和Java稍稍有所不同,它们的使用场景以及实现的目的是类似的,本质上都是为了抽象。通过接口提取出了一些方法,所有继承了这个接口的类都必然带有这些方法,那么我们通过接口获取这些类的实例就可以使用了,大大增加了灵活性。

但是Java当中的接口有一个很大的问题就是侵入性,说白了就是会颠倒供需关系。举个简单的例子,假设你写了一个爬虫从各个网页上爬取内容。爬虫爬到的内容的类别是很多的,有图片、有文本还有视频。假设你想要抽象出一个接口来,在这个接口当中定义你规定的一些提取数据的方法。这样不论获取到的数据的格式是什么,你都可以用这个接口来调用。这本身也是接口的使用场景,但问题是处理图片、文本以及视频的组件可能是开源或者是第三方的,并不是你开发的。你定义接口并没有什么卵用,别人的代码可不会继承这个接口。

当然这也是可以解决的, 比如你可以在这些第三方工具库外面自己封装一层,实现你定义的接口。这样当然是OK的,但是显然比较麻烦。

Golang当中的接口解决了这个问题,也就是说它完全拿掉了原本弱化的继承关系,只要接口中定义的方法能对应的上,那么就可以认为这个类实现了这个接口。

我们先来创建一个interface,当然也是通过type关键字:


type Mammal interface {
 Say()
}

我们定义了一个Mammal的接口,当中声明了一个Say函数。也就是说只要是拥有这个函数的结构体就可以用这个接口来接收,我们和刚才一样,定义Cat、Dog和Human三个结构体,分别实现各自的Say方法:


type Dog struct{}

type Cat struct{}

type Human struct{}

func (d Dog) Say() {
 fmt.Println("woof")
}

func (c Cat) Say() {
 fmt.Println("meow")
}

func (h Human) Say() {
 fmt.Println("speak")
}

之后,我们尝试使用这个接口来接收各种结构体的对象,然后调用它们的Say方法:


func main() {
    var m Mammal
    m = Dog{}
    m.Say()
    m = Cat{}
    m.Say()
    m = Human{}
    m.Say()
}

出来的结果当然和我们预想的一样:

四、总结

今天我们一起聊了面向对象中多态以及接口的概念,借此进一步了解了为什么golang中的接口设计非常出色,因为它解耦了接口和实现类之间的联系,使得进一步增加了我们编码的灵活度,解决了供需关系颠倒的问题。但是世上没有绝对的好坏,golang中的接口在方便了我们编码的同时也带来了一些问题,比如说由于没了接口和实现类的强绑定,其实也一定程度上增加了开发和维护的成本。

总体来说这是一个仁者见仁的改动,有些写惯了Java的同学可能会觉得没有必要,这是过度解绑,有些人之前深受其害的同学可能觉得这个进步非常关键。但不论你怎么看,这都不影响我们学习它,毕竟学习本身是不带立场的。今天的内容当中包含一些Java和面向对象的概念,只是用来引出后面golang的内容,如果存在部分不理解的地方,希望大家抓大放小,理解核心关键就好了,不需要细扣每一个细节。

以上就是浅谈Go语言多态的实现与interface使用的详细内容,更多关于Go 多态与interface的资料请关注编程网其它相关文章!

您可能感兴趣的文档:

--结束END--

本文标题: 浅谈Go语言多态的实现与interface使用

本文链接: https://www.lsjlt.com/news/128255.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 浅谈Go语言多态的实现与interface使用
    目录一、多态的含义二、抽象类与接口三、Golang中的接口四、总结一、多态的含义 对于Java或者是C++而言,我们在使用变量的时候,变量的类型是明确的。但是如果我们希望它可以宽松一...
    99+
    2022-11-12
  • Go语言多态和interface如何使用
    本文小编为大家详细介绍“Go语言多态和interface如何使用”,内容详细,步骤清晰,细节处理妥当,希望这篇“Go语言多态和interface如何使用”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。多态的含义对于...
    99+
    2023-06-27
  • Go语言中interface语法与使用实例分析
    这篇“Go语言中interface语法与使用实例分析”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Go语言中interfac...
    99+
    2023-07-02
  • Go语言中如何使用接口来实现多态性?
    Go语言是一种强类型、静态类型的编程语言,它支持面向对象编程(OOP)的特性,其中最重要的特性之一是多态性。多态性是面向对象编程中的一个重要概念,它允许不同的对象对同一消息做出不同的响应。本文将介绍Go语言中如何使用接口来实现多态性。 接口...
    99+
    2023-08-05
    对象 接口 数据类型
  • C/C++使用C语言实现多态
    目录1.多态的概念1.1什么是多态?1.2为什么要用多态呢?1.3多态有什么好处?2.多态的定义及实现2.1继承中构成多态的条件2.2虚函数2.3虚函数的重写2.4C++11 ove...
    99+
    2022-11-12
  • 浅析go语言实现的一些常用功能
    Golang(或也称为Go语言)是Google于2009年推出的一种新型编程语言,因其高效、简单、可靠性强等特点,近年来在IT领域越来越受到注目。本文将介绍Golang的一些基本原理以及如何使用它实现一些常用的功能。一、Golang的基本原...
    99+
    2023-05-14
    go语言 Golang
  • go语言使用什么实现的
    go语言使用称为Go Runtime的虚拟机实现的。Go语言的虚拟机是由C语言实现的,它负责Go程序的运行和管理,这个虚拟机可以在不同的操作系统上运行,包括Linux、Windows、macOS等,还提供了垃圾回收机制,可以自动管理内存,减...
    99+
    2023-07-10
  • Go语言中NumPy函数的实现与应用
    NumPy是Python科学计算的基本库之一,提供了快速高效的数组运算能力,支持广泛的数学函数和线性代数运算。它的功能强大,但对于Go语言开发者来说,NumPy在Go语言中并没有直接的实现。本文将介绍在Go语言中如何实现NumPy函数,并...
    99+
    2023-10-29
    numy 函数 linux
  • Go语言接口使用教程:如何在编程算法中实现多态?
    Go语言是一种强类型的编程语言,它支持接口类型。接口类型是一种抽象类型,它定义了一组方法集,但没有实现这些方法。因此,接口类型可以用来描述任何实现了这些方法的类型。在Go语言中,接口类型是实现多态的关键。 接口的定义 在Go语言中,接口类...
    99+
    2023-10-23
    接口 教程 编程算法
  • 详解Go语言中泛型的实现原理与使用
    目录前言问题解决方法类型约束重获类型安全泛型使用场景性能虚拟方法表单态化Go 的实现结论前言 原文:A gentle introduction to generics in G...
    99+
    2022-06-07
    详解go语言 GO 泛型 go语言
  • 浅析go语言转发功能的实现和应用场景
    随着互联网的飞速发展,网络技术得到了迅速的普及和应用,其优异的性能和稳定性为现代的web应用提供了强有力的支持。随着web应用的发展,语言也不断发展壮大,其中谷歌推出的go语言(golang)以其快速响应和高效率的特性,备受开发者青睐。近年...
    99+
    2023-05-14
    go语言 Golang
  • 如何使用Go语言实现多线程Websocket通信
    在近年来,实时通信已经成为了一种基本的需要。WebSocket则更是实时通信当中的佼佼者,它能够更快速、有效地实现客户端和服务器端之间的实时通信。而Go语言也作为近年来较火热的一种语言,被广泛应用于实时通信中。利用Go语言的优点以及多线程处...
    99+
    2023-12-14
    多线程 Go语言 Websocket通信
  • go语言使用jwt认证的实现
    目录加密解密这几天在学习nodejs,进一步了解npm,学习过程中解开了以前的一个疑惑,以前不知道token可以携带信息,只以为是用来做对比的,学到了jwt身份认证,知道了如何使用的...
    99+
    2022-11-13
  • 如何使用Go语言实现路由的静态文件服务
    如何使用Go语言实现路由的静态文件服务概述:在Web开发中,静态文件服务是非常常见且重要的功能。它通常用于提供网站的静态资源,例如HTML、CSS、JavaScript、图像等。本文将介绍如何使用Go语言实现一个简单的路由的静态文件服务,并...
    99+
    2023-12-17
    Go语言 路由 静态文件服务
  • Go语言开发物联网应用的实现与优化
    Go语言开发物联网应用的实现与优化随着物联网技术的快速发展,物联网应用在各个领域都得到了广泛应用。而作为一种高效、稳定、并发性能良好的编程语言,Go语言在物联网应用的开发中具有很大的优势。本文将介绍如何使用Go语言开发物联网应用,并针对物联...
    99+
    2023-11-20
    优化 Go语言 物联网应用
  • 使用Go语言写一个Http Server的实现
    目录调试功能1功能2功能3功能4Http Server 代码 go.mod: module goStudy1 go 1.17 main.go: package main imp...
    99+
    2022-11-13
  • 如何使用Go语言实现的api网关
    小编给大家分享一下如何使用Go语言实现的api网关,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!浏览器的请求去请求目标地址,然后获得结果它再发送给浏览器。对于Go语言来说,实现转发只需要简单的一行代码即可实现,如下所示:h...
    99+
    2023-06-21
  • 使用Go语言文档中的net/http.FileServer函数实现静态文件服务
    Go语言是一种简洁高效的编程语言,既可以用于开发网络应用程序,也可以用于实现静态文件服务。在Go语言的标准库中,提供了一个强大的net/http包,其中的FileServer函数可以帮助我们方便地实现静态文件服务。本文将详细介绍如何使用该函...
    99+
    2023-11-04
    net/http 关键词:Go语言 FileServer
  • 如何在go语言中实现高可用的系统设计与实现
    要在Go语言中实现高可用的系统设计与实现,可以遵循以下步骤:1. 设计分布式系统架构:首先,需要设计一个可扩展的分布式系统架构。这包...
    99+
    2023-10-12
    Go语言
  • Go语言实现23种设计模式的使用
    目录创建型模式工厂方法模式 Factory Method问题解决抽象工厂模式 Abstract Factory问题解决建造者模式 Builder问题解决原型模式 Prototype问...
    99+
    2022-11-13
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作