【Golang】 Struct, Method, Interfaceをまとめてみた

# はじめに
最近**Golang**をはじめまして、Struct, Method, Interfaceをまとめてみました。
※ 間違い等ございましたら、ご指摘お願い致します。

# Struct(構造体)
## 構造体とは？
Go言語にはオブジェクト指向における`Class`という物が存在しません。
しかし、それと似たような役割を果たしてくれる変数が**構造体**です。

## 定義方法

`struct`という型を使って定義します。

``` go
type Human struct {
	name string
	age  int
}
```

## 初期化方法

初期化方法はいくつかの方法があります。

1. `{}`を使い、順序にしたがって初期化する。<br />
`P := Human{"Sam",22}`
1. `field:value`の方法で初期化する。順序は任意。<br />
`P := Human{age:25, name:"Tom"}`
1. `new`関数を使い、変数定義後に初期化する。<br />
`P := new(Human)`

それでは、一通り宣言してみます。

``` go
type Human struct {
	name string
	age  int
}

func main() {
	// 1. {}を使い、順序にしたがって初期化する。
	sum := Human{"Sum", 22}
	// 2. field:valueの方法で初期化する。順序は任意。
	tom := Human{age: 25, name: "Tom"}
	// 3. new関数を使い、変数定義後に初期化する。
	bob := new(Human)
	bob.name, bob.age = "Bob", 28

	fmt.Printf("Name = %s Age = %d\n", sum.name, sum.age)
	fmt.Printf("Name = %s Age = %d\n", tom.name, tom.age)
	fmt.Printf("Name = %s Age = %d\n", bob.name, bob.age)
}
```

## 匿名フィールド

フィールドを継承して、新たなフィールドを宣言する方法です。
上記の`Human`を継承して`Student`を作成します。

``` go
type Human struct {
	name string
	age  int
}

type Student struct {
	Human	// 匿名フィールド
	speciality string
}

func main() {
	sum := Student{Human{"Sum", 22}, "Computer Science"}
	fmt.Printf("Name = %s Age = %d Speciality = %s\n", sum.name, sum.age, sum.speciality)
}
```

アクセスする際も、あたかも自分のフィールドのようにアクセスできます。

# Method(メソッド)

## メソッドとは？
任意の型に関連付けられた関数をメソッドと呼ぶ。

## 文法

``` go
func (r ReceiverType) funcName(parameters) results {
	// 処理
}
```

## 定義方法

とりあえず書いてみます。
まずは、`Circle`の構造体を作り、`area()`メソッドで面積を返します。

``` go
type Circle struct {
	radius float32	// 半径
}

func (c Circle) area() float32 {
	return c.radius * c.radius * math.Pi
}

func main() {
	c := Circle{5}
	fmt.Printf("半径%.0fcmの円の面積＝%.3fc㎡", c.radius, c.area())
}
```

## 匿名フィールドを使いメソッドを定義する

匿名フィールドを含む`sturct`もメソッドを定義することができる。

``` go
type Human struct {
	name string
	age  int
}

type Student struct {
	Human
	school string
}

type Employee struct {
	Human
	company string
}

func (s Student) SayHi() {
	fmt.Println("私は学生です。")
}

func (e Employee) SayHi() {
	fmt.Println("私は会社員です。")
}

func main() {
	tom := Student{Human{"Tom", 18}, "hoge"}
	sum := Employee{Human{"Sum", 30}, "fuga"}
	tom.SayHi()
	sum.SayHi()
}
```
同じ関数名で宣言しても名前空間が違うからエラーにはなりません。

# Interface（インタフェース）

## インタフェースとは？

簡単に言うと、「メソッドの組み合わせ」です。
メソッドの型だけを定義した型の一種であり、任意の型が**どのようなメソッドを実装するべきか**を規定するためのもの。

## 文法

``` go
type TypeName interface {
	MethodName(parameters) results
}
```

## 定義方法

``` go
// 車の構造体
type Car struct {
	speed int
}

// スポーツカーの構造体
type Sports struct {
	Car
	player string
}

// 走るためのインタフェース
type Runner interface {
	Place()
	Run()
}

func (c Car) Place() {
	fmt.Print("道路を")
}

func (c Car) Run() {
	fmt.Printf("%dキロで安全運転に走る。\n", c.speed)
}

func (s Sports) Place() {
	fmt.Print("コースを")
}

func (s Sports) Run() {
	fmt.Printf("%dキロで早く走る。\n", s.speed)
}

// インターフェスを引数に取る関数
func Run(r Runner) {
	r.Place()
	r.Run()
}

func main() {
	c := Car{40}
	s := Sports{Car{150}, "Tom"}
	// インタフェースのRunner型の変数を用意
	var r Runner
	r = c
	Run(r)
	r = s
	Run(r)
}
```

``` shell:出力結果
道路を40キロで安全運転に走る。
コースを150キロで早く走る。
```

### インタフェースを使った関数

引数にインタフェースを取ることで、インタフェースを使いまわすこともできる。

``` go
// インターフェスを引数に取る関数
func Run(r Runner) {
    r.Place()
    r.Run()
}
```

### 使い方

``` go
func main() {
    c := Car{40}
    s := Sports{Car{150}, "Tom"}
    // インタフェースのRunner型の変数を用意
    var r Runner
    r = c
    Run(r)
    r = s
    Run(r)
}
```

１. 構造体の定義
最初は構造体を定義しているだけです。

``` go
c := Car{40}
s := Sports{Car{150}, "Tom"}
```
２. インタフェースの型の定義(ポイント)
`r`は`Runner`型の変数です！

``` go
var r Runner
```

３. 構造体の実体をインターフェース型の変数に代入
この時点で`Car`型から`Runner`型に変換されたと認識してよい。

``` go
r = c
```

４. インタフェースを使った関数(`Run`)に`r`を渡す

``` go
Run(r)
```

これと同様にスポーツカーにもします。
そうすると普通の車とスポーツカーとの場合で結果が変わります。

インタフェースを使うと、プログラムの柔軟性を与えることができますね。