理解Go的多态实现

作者:神秘网友 发布时间:2021-01-25 13:38:09

理解Go的多态实现

总结两点:

  • 在Go中,定义一个interface类型,该类型说明了它有哪些方法。使用时,在函数中,将该interface类型作为函数的形参,任意一个实现了interface类型的实参都能作为该interface的实例对象。Go中没有implements关键字,与Java的实现多态相比,Go的组合更加灵活。
  • Go语言中没有继承,只有组合,可通过组合达到“继承”方法的目的。

先看一个例子:

/**
 * Animal 三个接口:fly(), swim() 和 run(),如果实现Animal,需要同时实现三个接口。
 */
public interface Animal {
    public void fly();
    public void swim();
    public void run();
}

class Dog implements Animal {
    @Override
    public void fly() {
        System.out.println("Dog can not fly");
    }

    @Override
    public void swim() {
        System.out.println("Dog can not swim");
    }

    @Override
    public void run() {
        System.out.println("Dog can run");
    }
}

class Fish implements Animal {
    @Override
    public void fly() {
        System.out.println("Fish can not fly");
    }

    @Override
    public void swim() {
        System.out.println("Fish can swim");
    }

    @Override
    public void run() {
        System.out.println("Fish can not run");
    }
}

再来看Go的实现:

type Animal1 interface {
	fly()
	swim()
	run()
}

type Dog1 struct {
}

func (d Dog1) run() {
	fmt.Println("dog can run")
}

type Fish struct {
}

func (f Fish) swim() {
	fmt.Println("fish can swim")
}

可以看到,Go中实现需要的功能更灵活。这是多个实现类之间的比较,实现更加灵活。再看类似于“父子”之间的继承。

import (
	"fmt"
	"reflect"
)

type Base struct {
	// nothing
}

func (b *Base) ShowA() {
	fmt.Println(reflect.TypeOf(b))
	fmt.Println("showA")
	b.ShowB()
}
func (b *Base) ShowB() {
	fmt.Println(reflect.TypeOf(b))
	fmt.Println("showB")
}

func (b *Base) ShowC() {
	fmt.Println(reflect.TypeOf(b))
	fmt.Println("showC")
}
//Derived 通过组合Base结构体,实现了伪继承,即拥有了ShowA和ShowB方法
type Derived struct {
	Base
}
//Derived 自己实现了ShowB方法,但不会自动做类型转换
func (d *Derived) ShowB() {
	fmt.Println(reflect.TypeOf(d))
	fmt.Println("Derived showB")
}

type NewBase Base

func main2() {
	d := Derived{Base{}}
	d.ShowA()  //Derived通过组合,有了ShowA()方法
	/**
	*main.Base
	showA
	*main.Base
	showB
	上述代码执行结果不会输出“Derived showB”,因为Go中没有继承的概念,只有组合.
	上面的Derived包含了Base,自动的含有了Base的方法,因为其不是继承,所以不会根据具体传入的对象而执行对应的方法。
	*/
	d.ShowB()
	/**
	*main.Derived
	Derived showB
	*/

	d.Base.ShowB()
	/**
	*main.Base
	showB
	d 通过组合获取了Base的方法 ShowB. 但如果d要调取Base的ShowB()方法(与d的ShowB()方法重复),需要显示调用Base.
	*/
	d.ShowC()
	/**
	*main.Base
	showC
	d 通过组合获取了Base的方法 ShowC.
	 */
	b := Base{}
	b.ShowC()
	//b1 := NewBase{}
	//b1.ShowC()  //没有ShowC()方法
	/**
	上面的代码中b1不能执行ShowC()函数,因为Golang不支持隐式类型转换.
	虽然newBase就是Base,但语法上它们是两种类型,因此newBase不能执行ShowC()方法。
	 */
}

理解Go的多态实现 相关文章

  1. 再见Excel!一行Pandas代码即可实现漂亮的 “条件格式”!

    本文概述 Pandas 是数据科学家做数据处理时,使用最多的工具。 对比Excel,我们可以发现: Pandas基本可以实现所有的Excel的功能,并且比Excel更方便、简洁,其实很多操作我们在过去的文章中,或多或少都讲述过。 但是在数据框上,完成各种 “条件格式” 的

  2. 综述:图像滤波常用算法实现及原理解析

    前言 本文介绍四种常见的图像滤波算法,并附上源码。图像滤波是一种非常重要的图像处理技术,现在大火的卷积神经网络其实也是滤波的一种,都是用卷积核去提取图像的特征模式。不过,传统的滤波,使用的卷积核是固定的参数,是由经验非常丰富的人去手动设计的

  3. Python实现Paramiko的二次封装

    Paramiko是一个用于执行SSH命令的Python第三方库,使用该库可实现自动化运维的所有任务,如下是一些常用代码的封装方式,多数代码为半成品,只是敲代码是的备份副本防止丢失,仅供参考。 实现命令执行: 直接使用过程化封装,执行CMD命令. import paramikossh

  4. lottie-前端实现AE动效

    在前端页面上为了实现动画效果,可以用 CSS3 自己实现,可以让UI小姐姐给你 GIF动图 ,也可以直接 animate.css 等等吧,可以实现的方式有不少,但如果说偏差那肯定是会有的,在呈现上也会有点不太自然,今天介绍一个神器Lottie。(刚接触到这个东西,那兴趣

  5. 分布式系统限流算法分析与实现

    一、限流的关键作用 对于大型互联网架构中,限流的设计是必不可少的一个环节。在给定的时间内, 客户端请求次数过多, 服务器就会拦截掉部分请求,避免请求流量过大造成数据库负载高的问题。 二、常见限流算法利弊分析 计数器限流 计数器限流主要有固定窗口计

  6. 对于线性回归通俗理解的笔记

    经常听说线性回归(Linear Regression) 到底什么才是线性,什么才是回归 有学者说,线性回归模型是一切模型之母。所以,我们的机器学习之旅,也将从这个模型开始! 建立回归模型的好处:随便给一个x,就能通过模型算出y,这个y可能和实际值不一样,这个y是

  7. 我用YOLO-V5实现行人社交距离风险提示,代码开源!

    CVer今天 以下文章来源于AI人工智能初学者,作者ChaucerG AI人工智能初学者 机器学习知识点总结、深度学习知识点总结以及相关垂直领域的跟进,比如CV,NLP等方面的知识。 点击上方“ CVer ”,选择加" 星标 "置顶 重磅干货,第一时间送达 本文转载自:AI人工

  8. ReactRouter的实现

    ReactRouter的实现 ReactRouter 是 React 的核心组件,主要是作为 React 的路由管理器,保持 UI 与 URL 同步,其拥有简单的 API 与强大的功能例如代码缓冲加载、动态路由匹配、以及建立正确的位置过渡处理等。 描述 React Router 是建立在 history 对象之上

  9. 基于SSD的Kafka应用层缓存架构设计与实现

    Kafka在美团数据平台承担着统一的数据缓存和分发的角色,针对因PageCache互相污染,进而引发PageCache竞争导致实时作业被延迟作业影响的痛点,美团基于SSD自研了Kafka的应用层缓存架构。本文主要介绍了该架构的设计与实现,主要包括方案选型,与其他备选方案

  10. 随笔-网络编程实现TCP协议传输文件

    客户端 需要注意的是,该代码偷懒,关闭资源操作,必须使用try-catch-finally,最好使用try-with-resources格式 public void client() { Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 9090 ); OutputStream os = socket.getOutputStream

每天更新java,php,javaScript,go,python,nodejs,vue,android,mysql等相关技术教程,教程由网友分享而来,欢迎大家分享IT技术教程到本站,帮助自己同时也帮助他人!

Copyright 2020, All Rights Reserved. Powered by 跳墙网(www.tqwba.com)|网站地图|关键词