前回はインターフェースを実装し使用してみました。
今回はインターフェースのメソッドの利点について説明します。
インターフェースのメソッドの利点
Goに限った話ではありませんが、インターフェースは「メソッドリストとそれらのメソッドの型(シグネチャー)が確約される」と言う利点があります。定義したメソッドリストの引数の数と型、戻り値の型が同じであればそのメソッドの処理内容は何でも良いのです。簡単に言うとIN、OUTさえ同じであれば処理の内容は何でも良いのです。
当たり前ですが、インターフェースを実装したインスタンスはインターフェースで定義したメソッドを必ず使用できる事になります。さらに言うと、インターフェースは定義したメソッドリストしか使用できないと言う事にもなります。
やりたいこと
インターフェースは定義したメソッドリストしか使用できない と言う事について実装してみます。前回は名前と年齢を表示するインターフェースを実装しました。今回は年齢を表示したくないという場合が仮にあったとします。その場合にどうすれば良いかを実装してみます。
インターフェースの定義は自由
前回はインターフェースの定義に名前(getName())と年齢(getAge())を取得できる2つのメソッドリストを定義しましたが、今回は名前(getName())を取得するメソッドのみを定義します。
// インターフェースの定義
type myInterface interface {
// 必要なメソットを記載する
getName() string
}
インターフェースの実装
今回は例としてインターフェースの実装を2つ定義します。
- 1つ目のインターフェースの実装は前回と同じです。(myStruct)
- 2つ目のインターフェースの実装は名前を取得するメソッド(getName())のみ定義します。(youStruct)
// 1つ目の構造体の定義
type myStruct struct {
name string
age int
}
// 1つ目の構造体のメソット定義
func (m myStruct) getName() string {
return m.name
}
// 1つ目の構造体のメソット定義
func (m myStruct) getAge() int {
return m.age
}
// 2つ目の構造体の定義
type youStruct struct {
name string
}
// 2つ目の構造体のメソット定義
func (y youStruct) getName() string {
return "苗字" + y.name
}
メソッドの確約
インターフェースを引数に持つ関数(showName())を作成します。
こうすることで、異なる型でもインターフェースが実装されているので、関数(showName())は引数で受け取った変数は、getName()を実装している事が確約されます。
func main() {
// 1つ目の構造体
var myParson myStruct
myParson.name = "名前"
showName(myParson) // "名前" が表示される。
// 2つ目の構造体
var youParson youStruct
youParson.name = "名前"
showName(youParson) // "苗字名前" が表示される。
}
// 名前を表示する関数
func showName(m myInterface) {
fmt.Println(m.getName())
}
なお、以下は実行できません。エラーになります。
func main() {
// 1つ目の構造体
var myParson myStruct
myParson.age = 10
showAge(myParson) // panic が発生する
}
// 年齢を表示する関数
func showAge(m myInterface) {
fmt.Println(m.getAge())
}