Go
golang

JSerがGolang始めてみた 〜 3. オブジェクト指向的な書き方を学ぶ

前回はDockerを使ってGolangを動かすところまでできました。

今回はWebAppは一旦置いておいて、Golangでのオブジェクト指向的な書き方を勉強します。
サンプルコードを読んでて頻繁に「なんだこれは!?」ってなったので・・・('A`)

クラス

まずはクラスから。といってもGolangにクラスはありません。あるのはC言語とかで馴染み深い構造体です。

構造体
type Person struct {
    name string
    age int
}

Golangでは、この構造体にメソッドを定義することでクラスっぽく利用することが出来ます。

構造体にメソッドを定義
type Person struct {
    name string
    age int
}

// Person構造体にSayHelloメソッドを追加
func (p *Person) SayHello() {
    fmt.Println("[" + p.name + "]< こんにちは!")
}

func main() {
    taro := &Person{"たろう", 20}
    taro.SayHello() // [たろう]< こんにちは!
}

※ ここで(p *Person)の部分を(p Person)としても動作します。値渡しか参照渡しかの違いです。説明は割愛

ES5時代のprototypeによるメソッド定義に似てますね。

クラスの継承

Golangにはクラスが無いので、もちろん継承という機能はありません。
上述の構造体を用いて継承のような機能を実現するためには、構造体をネストさせます。

クラスの継承
type Monster struct {
    name string
}

func (m *Monster) Attack() {
    fmt.Println(m.name + "の こうげき")
}

// Monsterを継承したSlimeを定義
type Slime struct {
    Monster
}

func (s *Slime) Call() {
    fmt.Println(s.name + "は なかまをよんだ")
}

// Slimeを継承したHealSlimeを定義
type HealSlime struct {
    Slime
}

func (h *HealSlime) Heal() {
    fmt.Println(h.name + "は たいりょくをかいふくした")
}

func main() {
    h := HealSlime{Slime{Monster{"ホイミン"}}}
    h.Attack() // ホイミンの こうげき
    h.Call()   // ホイミンは なかまをよんだ
    h.Heal()   // ホイミンは たいりょくをかいふくした
}

ちゃんと継承元のメソッドも呼べてますね。

カプセル化

Golangでは、公開範囲は名前の先頭が大文字か小文字かで決まります。
大文字ならpublic、小文字ならprivateです。

カプセル化
type Person struct {
    Name string
    age int // 年齢は非公開
}

// GetAgeメソッドは公開
func (p *Person) GetAge() int {
    return age - 5
}

// getRealAgeメソッドは非公開
func (p *Person) getRealAge() int {
    return age
}

おわり

次回こそ、WebAppの開発に着手します。

続く