インターフェース入門
CoddyのGOジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 25/107。
Go の interface は、実装を伴わずに一連の method シグネチャを定義します。これは型が何をできるかを記述するものであり、どのように実行するかを記述するものではありません。interface 内のすべての method を実装する型は、自動的にその interface を満たします。
interfaceを定義する方法は次のとおりです。
type Speaker interface {
Speak() string
}この Speaker インターフェースは、これを実装する任意の型に、文字列を返す Speak() メソッドがあることを要求します。これで、このメソッドを持つ任意の構造体を、Speaker が必要とされる場所で使用できます。
type Dog struct {
Name string
}
func (d Dog) Speak() string {
return d.Name + " says woof!"
}
type Cat struct {
Name string
}
func (c Cat) Speak() string {
return c.Name + " says meow!"
}Dog と Cat は、それぞれ正しいシグネチャの Speak() メソッドを持っているため、どちらも Speaker インターフェースを満たします。これで、任意の Speaker を受け取る関数を記述できるようになりました。
func MakeSound(s Speaker) {
fmt.Println(s.Speak())
}
func main() {
dog := Dog{Name: "Buddy"}
cat := Cat{Name: "Whiskers"}
MakeSound(dog) // Buddy は woof! と言う!
MakeSound(cat) // Whiskers は meow! と言う!
}interface の要件を満たす any の型で、基盤となる実装に関係なく動作する、柔軟で再利用可能なコードを記述できます。
チャレンジ
簡単異なる型が共通の動作を共有できる仕組みをインターフェースで示す、車両の説明システムを構築しましょう。複数の車両型が満たせるインターフェースを作成し、それを使って any 車両を統一的に説明します。
コードを 2 つのファイルに分けて整理します。
vehicles.go: 1 つのメソッドDescribe() stringを持つDescriberインターフェースを Define します。次に、このインターフェースを満たす 2 つの構造体を作成します。Car—BrandとModelの fields(both とも文字列)Bicycle—Type(文字列)とGears(int)の fields
Describe()メソッドを実装します。main.go: anyDescriberを accepts し、そのDescribe()メソッドを calling した結果を表示する、PrintDescriptionという名前の function を作成します。input から車両情報を読み取り、Car と Bicycle の both を作成して、function を使ってそれぞれの説明を表示します。
次の input が提供されます。
- 1 行目: Car brand
- 2 行目: Car model
- 3 行目: Bicycle type
- 4 行目: Gears の数(整数)
Describe() メソッドは、次の形式の文字列を返す必要があります。
- Car:
[Brand] [Model] - Bicycle:
[Type] bike with [Gears] gears
たとえば、Toyota、Camry、Mountain、21 が与えられた場合、出力は次のようになります。
Toyota Camry
Mountain bike with 21 gears重要なポイントは、PrintDescription function が Describe() メソッドを持つ any 型で動作することです。Car、Bicycle、または後で追加する可能性のあるその他の車両型のどれを扱っているかを知る必要はありません。
自分で試してみよう
package main
import (
"fmt"
)
// TODO: 任意の Describer を受け取る PrintDescription 関数を作成する
// そしてその Describe() メソッドを呼び出した結果を出力する
func main() {
// 入力を読み取る
var carBrand string
var carModel string
var bicycleType string
var gears int
fmt.Scanln(&carBrand)
fmt.Scanln(&carModel)
fmt.Scanln(&bicycleType)
fmt.Scanln(&gears)
// TODO: 入力からブランドとモデルを使って Car を作成する
// TODO: 入力からタイプとギアを使って Bicycle を作成する
// TODO: PrintDescription を使って車の説明を出力する
// TODO: PrintDescription を使って自転車の説明を出力する
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
1Go オブジェクト指向の基礎
外部ファイルGo ワークスペースとモジュールパッケージとインポート公開された名前と非公開の名前Go におけるオブジェクト指向入門クラスとしての構造体構造体へのメソッド定義ポインタレシーバと値レシーバ構造体の初期化コンストラクタ関数まとめ:簡易計算機8エラー処理とOOP
error インターフェースカスタムエラー型エラーラッピング (fmt.Errorf)センチネルエラーerrors.Is() と errors.As()Panic、Defer、Recover復習 - ファイルパーサー自分で練習してみよう: Goオンラインコンパイラ