美文网首页
关于go面向对象、泛型的新理解

关于go面向对象、泛型的新理解

作者: hijiang | 来源:发表于2019-05-23 01:17 被阅读0次

说到面向对象,总想到的是C++,最近看go,感觉其接口设计用起来也是蛮爽的;
go的接口只需要对应的结构体实现了相应接口的方法(一样参数,一样返回值),那么go就可以实现类似C++的运行时多态:可以将一个实现了该接口的结构体实例传入函数参数中,实现多态效果,但是go的语法没有C++限制那么严格,不需要通过冒号去写继承的代码,只需要实现接口那些函数就认为实现那个接口了。
很好理解,既然都实现了那些接口的函数,那就可以认为实现了那个接口,简单直接,省去了C++的继承代码,虽然可能会稍微导致代码不可读性,但是只要有好的命名习惯,就还是很容易可以知道某个结构的函数是个对象的。

我们知道go的interface可以等于任何值,这为多态实现提供便利;
我们使用一个例子来考虑用go怎么写:
首先假设动物有吃东西这个接口,用go描述:
···
type Animal interface {
Eat(food interface{})
}
···
我们将Eat的参数使用interface,表示可以接收任何类型的参数(虽然这样也不太对,应该是食物才对,暂且这么写吧)
然后,我们考虑人和猴子两个对象,都属于动物,那他们都应该实现Animal的接口吧,同时我们给他们加上一些属性,如体重,名称吃喝拉撒什么的都要有,用go描述:

type Human struct {
  Weight int
  Name string
}

type Monkey struct {
  Weight int
  Kind string 
}

然后对应的接口实现描述:

func (this *Human) Eat(food interface{}) {
  fmt.Println("human "+ this->Name + " eat a " + food.(string))
}

func (this *Monkey) Eat(food interface{}) {
  fmt.Println("monkey eat a " + food.(string))
}

写个main函数试试

package main
import (
  "fmt"
)

func main() {
  human := &Human{Weight:100,Name:"hijiang"}
  monkey := &Human{Weight:60, Kind:"金丝猴"}
  human.Eat("apple")
  monkey.Eat("bannaner")
}

最后输出:

  • human hijiang eat a apple
  • monkey eat a bannaner

如果再进一步考虑,食物还不应该是随便一种类型,需要有限制,那么用go描述一个食物:

type Food interface {
  GetWeight() int
  GetName() string
}
//我们特意将其成员变量小写,然后实现个接口,分别获取食物的重量和名称

接下来我们实现一个具体的食物apple和bannaner吧:

type Apple struct {
  weight int
  name string
}

type Bannaner struct {
  weight int
  name string
}

func (this *Apple ) GetWeight() int {
  return this.weight
}

func (this *Apple ) GetName() string {
  return this.name
}

func (this *Bannaner) GetWeight() int {
  return this.weight
}

func (this *Bannaner) GetName() string {
  return this.name
}

接下来我们限制下Animal接口只能输入Food类型(其实,Food是接口类型的话,可以接受任何类型):

type Animal interface {
  Eat(food Food)
}

然后修改下Human和Monkey的接口:

func (this *Human) Eat(food Food) {
  fmt.Println("human "+ this->Name + " eat a " + food.GetName()+",weight="+food.Weight())
}

func (this *Monkey) Eat(food Food) {
  fmt.Println("monkey eat a " + food.GetName()+",weight="+food.Weight())
}

main:

func main() {
  human := &Human{Weight:100,Name:"hijiang"}
  monkey := &Human{Weight:60, Kind:"金丝猴"}
  apple := &Apple{weight:100,name:"苹果"}
  bannaner := &Bannaner{weight:200, name:"香蕉"}
  human.Eat(apple)
  monkey.Eat(bannaner)
}

代码编写过程发现,函数名称一样接收器不一样是会被视为重复定义的,这个暂时还没搞明白为什么要这样。
关于go的结构体类貌似是不能用来做类似这种多态编程,暂时不研究。

相关文章

  • 关于go面向对象、泛型的新理解

    说到面向对象,总想到的是C++,最近看go,感觉其接口设计用起来也是蛮爽的;go的接口只需要对应的结构体实现了相应...

  • GLSL常用内建函数

    genType可以理解为泛型 genType pow(genType x)genType有点像面向对象中泛型,即如...

  • 面向对象-泛型

    面向对象-泛型 没有泛型存在的问题 1.往集合当中存储元素,可以存储任何类型元素 2.没有办法约束集合当中只能存储...

  • java 泛型解析

    Java 泛型 1、泛型的精髓是什么 2、泛型方法如何使用 概述: 泛型在java中具有重要地位,在面向对象编程模...

  • 8.泛型

    泛型历史和概述 泛型发展 泛型程序最早出现1970年代的CLU和Ada语言中,后来被许多基于对象和面向对象的语言所...

  • Swift语法学习

    1.Swift既支持面向过程的编程机制,也支持面向对象的编程方式。(c++支持泛型编程,mark泛型编程) 2.S...

  • Swift 面向协议编程

    面向协议编程你可能听过类似的概念:面向对象编程、函数式编程、泛型编程,再加上苹果新提出的面向协议编程,这些统统可以...

  • go 泛型

    go 泛型 1. 类型参数(Type parameters) Go语言的泛型(Generic)叫做类型参数。泛型可...

  • TS 面向对象 -- 泛型

    泛型generic:参数化的类型,一般用来限制集合的内容 class News { ... ... }class ...

  • 面向对象(十二)-泛型

    1. 简介: 2.0 版 C# 语言和公共语言运行时 (CLR) 中增加了泛型。 泛型将类型参数的概念引入 .NE...

网友评论

      本文标题:关于go面向对象、泛型的新理解

      本文链接:https://www.haomeiwen.com/subject/trrmzqtx.html