golang也能实现抽象类了?

本文介绍了一种通过 struct 和 interface 来在 golang 中实现抽象类的方式。

前言

在 Java 这种面向对象的语言中,抽象类和接口是我们经常会运用到的 2 种对抽象概念进行定义的机制。在 golang 中,没有类和继承的概念。golang 中有结构体(struct),和面向对象语言中的类相似。golang 中也有接口(interface),接口可以定义一组不含有具体实现的方法,其提供了一种方式来说明对象的行为。

然而,在某些情况下,我们需要使用抽象类继承,来帮助我们写出更优雅的代码。可是在 golang 中又没有抽象类的概念,本文将介绍一种通过 struct 和 interface 来在 golang 中实现抽象类的方法。

正文

首先,我们会用 Java 语言作为示例,来看看如何在面向对象语言中实现抽象类。接着换 golang 语言,通过 struct 和 interface 来实现抽象类,完成相同的功能。

面向对象语言中抽象类的实现

假设我们需要实现下面这样的几个类(使用 Java 为例):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public abstract class Game
{
public void play()
{
System.out.println(this.name() + " is awesome!");
}
public abstract String name();
}
public class Dota extends Game
{
public String name()
{
return "Dota";
}
}
public class LOL extends Game
{
public String name()
{
return "LOL";
}
}

我们定义了 Game 抽象类,在此类中定义了 public abstract String name(); 一个抽象方法和 public void play() 这样一个公开方法。然后我们定义了 DotaLOL 2个类去继承 Game,并各自实现了 public String name()

接下来让我们看看如何在 golang 中实现抽象类。

golang 中实现抽象类的方式

  • 定义 interface

首先,我们需要将抽象方法定义在 interface 中。

1
2
3
type IGame interface {
Name() string
}
  • 定义”父类”

然后,我们需要使用 struct 实现公共方法。

1
2
3
4
5
type Game struct {}
func (g *Game) play(game IGame) {
fmt.Printf(fmt.Sprintf("%s is awesome!", game.Name()))
}

这里是重点,我们将 game IGame 传了进来。这样我们便可以调用”子类”的方法来获取名字。从而间接地实现了在公共方法中调用不同”子类”的实现的抽象方法。

  • 定义”子类”

接着,我们再定义”Dota”和”LOL”这 2 个 struct 即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
type Dota struct {
Game
}
func (d *Dota) Name() string {
return "Dota"
}
type LOL struct {
Game
}
func (l *LOL) Name() string {
return "LOL"
}
  • 大功告成

现在,在初始化”Dota”和”LOL”结构体后,便可以调用 func (g *Game) play(game IGame) 方法了。

1
2
3
4
5
6
7
8
9
dota := &Dota{}
dota.play(dota)
lol := &LOL{}
lol.play(lol)
// 输出:
//Dota is awesome!
//LOL is awesome!

总结

本文通过 struct 和 interface 的组合,提供了一种思路,间接实现了面向对象语言中的抽象类继承的模式。旨在提供一种思路,希望能帮助到需要的同学,欢迎讨论 :)

当前网速较慢或者你使用的浏览器不支持博客特定功能,请尝试刷新或换用Chrome、Firefox等现代浏览器