LoginSignup
17
3

More than 3 years have passed since last update.

ダックタイピング についての覚書

Last updated at Posted at 2018-12-17

はじめに

ダックタイピングは、巷ではよく「もしもそれがアヒルのように歩き、アヒルのように鳴くのなら、それはアヒルである」
と表現されます。どういうことなのでしょうか。
Go言語で簡単なソースをコーディングしてみました。コメントベースで追っていきましょう。

ソース


package main

import "fmt"

// Fish interfaceは Swimメソッドを持つ。
type Fish interface {
    Swim() string
}

// Bird interfaceは Flyメソッドを持つ。
type Bird interface {
    Fly() string
}

// アヒルは泳げるし、少し飛べる。
// それらを踏まえて Duck ストラクトを定義する。
type Duck struct {
    duckSwim string
    duckFly  string
}

// Duck ストラクトにSwimメソッドを持たせる。
func (d *Duck) Swim() string {
    return d.duckSwim
}

// Duck ストラクトにFlyメソッドを持たせる。
func (d *Duck) Fly() string {
    return d.duckFly
}

// このFishSwim関数は Fish interface以外の引数は取らない
func FishSwim(f Fish) string {
    return f.Swim()
}

// このBirdFly関数は Bird interface 以外の引数は取らない
func BirdFly(b Bird) string {
    return b.Fly()
}

func main() {
    // 先程定義したストラクト Duckに文字列をセット
    dc := &Duck{
        "私は泳げます。",
        "私は飛べます。",
    }

    // アヒルなので、泳げる。
    fmt.Println(dc.Swim())
    // アヒルなので、飛べる。
    fmt.Println(dc.Fly())

    // FishSwim関数の引数はFishのみのはずだが、Duckを渡すと泳げると言う。
    fmt.Println(
        "SaySwim :",
        FishSwim(dc),
    )

    // BirdFly関数の引数はBirdのみのはずだが、Duckを渡すと飛べると言う。
    fmt.Println(
        "SayFry :",
        BirdFly(dc),
    )
}

まとめ

引数にFishしか受け取らないはずのFishSwim関数と
引数にBirdしか受け取らないはずのBirdFly関数が
Duckストラクトを受け取って「飛べる」とか「泳げる」とか言えるようになりました。
インターフェイス型のFish,Birdが必要なメソッドを持っていたからですね。
オブジェクトの振る舞いが問題なければ、
それを必要な引数として取り扱える事が
ダックタイピングの概要でしょうか。

17
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
3