😀

[Go] ポリモーフィズムをつかって綺麗な実装を目指そう

2024/03/09に公開

概要

インターフェースを使ったポリモーフィズムについてまとめる

必要な前提知識は以下の二つ(もし分からなければこちらの記事の上の方を参照ください)
・インターフェースの定義の仕方
・インターフェースを実装する方法

メリットは
ロジック内にはインターフェースしか現れないこと

インターフェース とは

インターフェースは言葉通り、境界面のイメージ
つまり、外から見た時に表面に何があるかを表している

Golangではインターフェースはメソッドの一覧で定義されているので
外からはこのメソッド一覧が見えて、そのメソッド一覧を使う事ができる

ポリモーフィズム とは

ある一つのインターフェースを実装した複数のオブジェクトに対して、そのインターフェースで公開されたメソッドで共通の処理をできること
開発者はインターフェースに命令することを意識すれば良い
どの構造体がこのインターフェースを実装したかは考えなくて良い

下のコードでは、猫か犬のどちらが来たかを判断して名前を判定している

変数の型指定やメソッドを呼ぶ時には、インターフェースのIAnimalしか意識していない事が分かる
具体的なDogとCatを意識するのは、それらを生成するときだけである

package main

import (
	"fmt"
)

type IAnimal interface {
	GetName() string
}

type Dog struct {
	name string
}

func (d Dog) GetName() string {
	return d.name
}

type Cat struct {
	name string
}

func (c Cat) GetName() string {
	return c.name
}

func main() {
	var animals []IAnimal = []IAnimal{
		Dog{"ポチ"},
		Cat{"ミケ"},
		Cat{"タマ"},
	}

	for _, animal := range animals {
		fmt.Println(animal.GetName())
	}
}

まとめ

インターフェースを実装する事で、ロジック内にインターフェースしか現れない事が分かった

補足1
今回はインターフェースを実装した場合でポリモーフィズムを考えたが、継承に関してもポリモーフィズムは適用できる
仮に構造体PoodleをDogから継承させた場合もPoodle型はインターフェースであるIAnimalとして扱う事ができる

補足2
今回は作らなかったがICat、IDog、IPoodleなどのインターフェースを作る事で
ICatを実装もしくは継承したオブジェクトだけが使える機能をICatで公開することもできる
インターフェースが役割を決め、それを実装や継承したものはその役割を持つという事が考えられる

Discussion