Help us understand the problem. What is going on with this article?

クラスとオブジェクトの関係性(Go 言語編)

More than 1 year has passed since last update.

面白い記事を見つけたので。

これを Go 言語に置き換えて語り直してみます。なお,私の個人ブログでもオブジェクトについて解説しているので,こちらも参考にどうぞ。


たい焼きの型(クラス)を作ってみる

「クラス」とは 名前,属性,操作 の3つの情報を持つ構造を定義したものです。「クラスとオブジェクトの関係性」の「たい焼き」クラスを例にすると

  • 名前:
    • Taiyaki
  • 属性:(なし)
  • 操作:
    • atama
    • shippo

という構造を指します。言い方を変えるなら上記の構造を記述できるものであればクラスとして定義できます。

ちなみに,ひとつのクラスに対してユニークな名前が1つのみ必ず存在します。属性と操作はそれぞれゼロ個以上存在します。

クラスとオブジェクトの関係性」では Ruby を使って記述していますが, Ruby にはクラスを定義するためのキーワード class が存在します。

class Taiyaki
    def atama
        puts "たい焼きの頭の方にはあんこがいっぱい入っている"
    end

    def shippo
        puts "たい焼きの尻尾にはあんこがほとんど入っていない"
        puts "しかしカリカリしていて美味しい"
    end
end

一方, Go 言語には Ruby で言うところの class に相当する構文は存在しません。その代わり Go 言語ではキーワード type を使った型宣言を使います。

type Taiyaki struct{}

func (t Taiyaki) Atama() {
    fmt.Println("たい焼きの頭の方にはあんこがいっぱい入っている")
}

func (t Taiyaki) Shippo() {
    fmt.Println("たい焼きの尻尾にはあんこがほとんど入っていない")
    fmt.Println("しかしカリカリしていて美味しい")
}

このように type 構文によって「型」を定義します。 type の名前がそのままクラスの名前に相当します。 Taiyaki 型 a.k.a Taiyaki クラスには属性がないため,空の構造体 struct{} を当てています。

func (t Taiyaki) Atama() {} の部分は関数定義です。このうち (t Taiyaki) の部分は「メソッド・レシーバ」と呼ばれるもので, Taiyaki クラスに対して Atama 関数を「操作」として関連付ける働きがあります。

たい焼き(インスタンス)を作ってみる

「インスタンス(instance)」は実体とか実例とか訳されるもので,定義であるクラスから生成した実体・実例がインスタンスというわけです。

厳密にはクラスとは「クラス・オブジェクト(class object)」で,インスタンスとは「インスタンス・オブジェクト(instance object)」です。両者とも「オブジェクト」ですが意味が異なるということですね。

さて「クラスとオブジェクトの関係性」によると Ruby におけるインスタンス生成は以下のように記述するようです。

taiyakikun_1gou = Taiyaki.new
taiyakikun_2gou = Taiyaki.new

このように,ひとつのクラスに対していくつでもインスタンスを生成できます。

一方, Go 言語でインスタンスを生成する方法はいくつかあるのですが,一番簡単なのは var キーワードによる宣言構文です。

var taiyakikun1gou Taiyaki
var taiyakikun2gou Taiyaki

あるいは,まとめて

var taiyakikun1gou, taiyakikun2gou Taiyaki

とも書けます。別の記述としては new() 関数を使い

taiyakikun1gou := new(Taiyaki)
taiyakikun2gou := new(Taiyaki)

と書くこともできます。

Ruby の new はクラス・メソッドで(class 定義の内容によって)引数を含めることができ,これによってインスタンスの内部状態を初期化できます。

一方の Go 言語var:= は宣言構文です1Go 言語でインスタンス生成時に初期化するには

taiyakikun1gou := &Taiyaki{}

のようにリテラルで表現するか

func New() *Taiyaki {
    return &Taiyaki{}
}

のようにインスタンスを生成(Ruby で言うところのインスタンス化)する関数を作るのがセオリーになっています。

では,最終的な Go 言語のコードを以下に示すとしましょう。

package main

import "fmt"

type Taiyaki struct{}

func (t Taiyaki) Atama() {
    fmt.Println("たい焼きの頭の方にはあんこがいっぱい入っている")
}

func (t Taiyaki) Shippo() {
    fmt.Println("たい焼きの尻尾にはあんこがほとんど入っていない")
    fmt.Println("しかしカリカリしていて美味しい")
}

func main() {
    var taiyakikun1gou Taiyaki
    taiyakikun1gou.Atama()
    taiyakikun1gou.Shippo()

    var taiyakikun2gou Taiyaki
    taiyakikun2gou.Atama()
    taiyakikun2gou.Shippo()
}

まとめ

「たい焼き」クラスを通して class キーワードのない Go 言語でクラスやインスタンスについてちょっとだけ掘り下げて考えてみました。



  1. taiyakikun1gou := new(Taiyaki)var taiyakikun1gou = new(Taiyaki) と同義です。また new() 関数の返り値はインスタンスそのものではなく,インスタンスへの参照(ポインタ)が返ります。 

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした