Ruby超入門コース#13 クラス

はじめに

こんにちは。キノコードです。
「Python超入門コース#13 クラス」について説明します。

クラスとは?

クラスの説明をする前に、レッスン7で学んだ内容を3つ、簡単に復習します。
1つ目。Rubyでは、すべての値がオブジェクトであること。
2つ目。オブジェクトは、クラスから作ることができること
3つ目。オブジェクトは何らかのクラスに所属している。
ということです。
これを前提に、インスタンスという言葉について説明します。
Rubyでは、オブジェクトのことを、インスタンスといったりもします。
つまり、オブジェクトとインスタンスはほぼ同じ意味なのです。
強いていうなら、オブジェクトがあるクラスに所属しているということを強調したい場合には、オブジェクトではなくインスタンスという言葉を使われることあります。
いずれにせよ、オブジェクトとインスタンスはほぼ同じ意味ということを覚えておきましょう。
さて、クラスについて説明していきます。
クラスとは、「データ」と「処理」をまとめたものになります。
Rubyでは、「データ」のことをインスタンス変数といい、「処理」のことをメソッドといいます。
インスタンス変数は、クラス内で定義された変数のことです。
インスタンス変数は、今までみてきた変数と同じように、数値や文字列を代入したり、参照したりすることができます。
クラスにインスタンス変数を作ることを「インスタンス変数を定義する」といいます。
インスタンス変数と変数の違いは、簡単にいってしまうと、クラスの外にあるかクラスの中にあるかの違いです。
また、インスタンス変数は、クラスの中でしか使えないという通常の変数との違いがあります。
「処理」のことをメソッドといいます。
メソッドについては、前のレッスンで説明をしました。
しかし、クラスの中にメソッドを書いたわけではありません。
クラスの外に書くメソッドのことを、関数的メソッドといいます。
そして、クラスの中に書いたメソッドのことをインスタンスメソッドといいます。
クラスの中に書いたメソッドには、インスタンスメソッドの他に、クラスメソッドというのもあります。
このレッスンでは、一般的なメソッドであるインスタンスメソッドについて説明します。
また、このレッスンでは、インスタンスメソッドのことを、単純にメソッドと呼んで説明していきます。

クラスの定義方法

それでは、実際にコードを書いてクラスを定義していきましょう。
どんなクラスを定義するか説明します。
クラス名はStudentとします。
そのクラスに生徒の名前を代入する「name」というインスタンス変数を定義します。
そして、数学と英語の点数の平均を計算するavgというメソッドを定義します。

class Student

    def avg()
        p (80 + 70) / 2
    end
end

まずClassと書いて、次にクラス名を書きます。
今回はStudentというクラス名なので、Student。
クラスの最初は大文字にしましょう。
次にメソッドを定義していきます。
数学と英語の点数の平均を計算するメソッドです。
平均を算出するので、平均という意味のaverageを省略して、avgというメソッド名にします。
メソッドの書き方は、前のレッスンで説明したものとおなじです。
まずdefと書いて、メソッド名。
改行です。
数学が80点と、英語が70点を取れたとして、それらを足して2で割ります。
表示させるためにpメソッドでくくりましょう。

クラスの使い方

class Student

    def avg()
        p (80 + 70) / 2
    end
end

a001 = Student.new
a001.avg

メソッドに引数を渡す

クラスを実際に使ってみたいと思いますが、クラスはこのままでは使うことができません。
クラスは、クラスからオブジェクトを作ってから使うことができます。
クラスからオブジェクトを作ることを「オブジェクト化」「オブジェクト生成」「インスタンス化」といったりします。
オブジェクトの作り方をみていきましょう。
クラス名を書いて、ドット、newです。つまり、Student.newと記述します。これでオブジェクトを作ることができます。
そして、生成されたオブジェクトを変数に格納します。
数学が80点、英語が70点という点数は、aという学級の出席番号001番の人がとったとします。
したがって、変数名をa001とします。
イコールを書いてオブジェクトa001にを代入します。
これで、クラスを使えるようになりました。
a001はオブジェクトです。クラスから生成されたオブジェクトなので、インスタンスと言われることもあります。
次にメソッドの実行方法についてです。
a001にドットをつけて、メソッド名です。
それでは実行してみましょう。
平均点の75点が表示されました。
ここまでは、80点と70点を直接をメソッド内に記述していました。
これだと生徒が変わるごとにメソッドの書き換えが必要です。
これを引数で渡して計算できるようにしましょう。
そうすることで、クラスの書き換えは不要になり、クラスを使い回すことができます。

class Student

    def avg(math, english)
        p (math + english) / 2
    end
end

a001 = Student.new
a001.avg(80,70)

クラス内に記述しているメソッドの1番目の引数をmathとします。
2番目の引数をenglishとします。
このmathとenglishの引数を、pメソッドのところに記述します。
avgメソッドに80点と70点を渡して実行してみましょう。
75点となるはずです。
実行してみます。
75が表示されました。

class Student

    def avg(math, english)
        p (math + english) / 2
    end
end

a001 = Student.new
a001.avg(30,70)

メソッドに渡す引数を30点と70点にしてみましょう。
平均の50が表示されるはずです。
実行してみましょう。
50が表示されました。

インスタンス変数

class Student
    def initialize
        @name = "sato"
    end 

    def avg(math, english)
        p @name,(math + english) / 2
    end
end

a001 = Student.new
a001.avg(30,70)

このレッスンの最初の方で、クラスはデータと処理をまとめたものだとお話ししました。
つまり、クラスはデータを持つことができます。
これがインスタンス変数です。
インスタンス変数を定義してみましょう。
インスタンス変数をinitializeメソッドというメソッドに記述していきましょう。
ところで、initializeメソッドとはなんでしょうか?
initializeメソッドは、オブジェクトを生成をする自動的に実行される特殊なメソッドです。
ここにインスタンス変数を定義することにより、オブジェクトを生成すると同時に値を渡すことができます。
まず、defと書き、initialize。
インスタンス変数は変数名の前に@(アットマーク)をつけます。
このインスタンス変数にsatoを代入しましょう。
終わりにはendを記述しましょう。
このインスタンス変数は、オブジェクトのメソッドからのみ参照することができます。
したがって、avgメソッドからはnameを参照することができます。
参照できるか、平均点を計算している前のところで表示してみましょう。
実行してみます
satoと平均点の50が表示されました。

class Student
    def initialize(name)
        @name = name 
    end 

    def avg(math, english)
        p @name,(math + english) / 2
    end
end

a001 = Student.new("sato")
a001.avg(30,70)

このインスタンス変数に、オブジェクト生成と同時に、データを渡すこともできます。
イニシャライズのあとに、丸括弧。丸括弧の中に引数を書きます。
この引数をインスタンス変数に代入します。
これでクラスの定義は完了です。
オブジェクト生成をするときに丸括弧を書き、satoを渡してみましょう。
実行してみます
satoと平均点の50が表示されました。
このように記述をすると、オブジェクトを生成するときにインスタンス変数に値を渡すことができます。


class Student
    def initialize(name)
        @name = name 
    end 

    def avg(math, english)
        return @name,(math + english) / 2
    end
end

a001 = Student.new("sato")
p a001.avg(30,70)

また、クラス内に記述したメソッドはreturnで返すこともできます。
pではなくreturnを記述しましょう。
また、avgメソッドを呼び出すところでpを記述して表示させてみましょう。
実行します。
satoと50が表示されました。

アクセス

class Student
    def initialize(name)
        @name = name 
    end 

    def avg(math, english)
        return @name,(math + english) / 2
    end

    attr_accessor :name

end

a001 = Student.new("sato")
p a001.name,a001.avg(30,70)

このインスタンス変数は、オブジェクトのメソッドからのみ参照することができると説明しました。
しかし、アクセサを使うと、インスタンス変数をオブジェクトの外から参照できるようになります。
このようにアクセサを記述します。
a001.nameと記述して、avgメソッドともに表示させてみましょう。
ただし、pメソッドのところでnameを表示させているので、returnのところのnameは消しておきましょう。

class Student
    def initialize(name)
        @name = name 
    end 

    def avg(math, english)
        return (math + english) / 2
    end

    attr_accessor :name

end

a001 = Student.new("sato")
p a001.name,a001.avg(30,70)

実行してみます。
satoと50が表示されました。
また、クラスは使い回しができます。
試しに、a002というオブジェクトを作って、インスタンス変数を渡して、使い回しができるか試してみましょう。

クラスの便利なところ


class Student
    def initialize(name)
        @name = name 
    end 

    def avg(math, english)
        return (math + english) / 2
    end

    attr_accessor :name

end

a001 = Student.new("sato")
p a001.name,a001.avg(30,70)


a002 = Student.new("suzuki")
p a002.name,a002.avg(90,80)

a002というオブジェクトを作って、オブジェクト生成のときにsuzukiという値を渡してみます。
メソッドに渡す点数を90と80にして呼び出してみましょう。
suzukiと85が表示されました。
以上がクラスの使い方です。
このクラスの便利なところはどんなところでしょうか?
クラスは一度、定義しておけば、あとからいくらでもインスタンスを作ることができます。
車を作る「設計図」がクラス、たい焼きを作る「金型」がクラスと表現したりもします。
もう1つ表現するなら、クラスは、パソコンで使うコピペです。
コピペでどんどんインスタンスを作ることができます。
もしクラスがなければ、生徒ひとりひとりのためにStudentクラスを書かなければいけないので面倒です。
しかしクラスがあるから、コピペのように各生徒のインスタンスを作ることができます。
クラスがあるから効率よくプログラミングすることができます。

確認問題

最後に確認問題をやっていきましょう。
このレッスンでは新しい用語がたくさんでてきたので、それを確認してみましょう。

(1)initializメソッドは、何を生成したときに自動的で実行されるメソッドなのでしょうか?
(2)Student.newでは何を生成しているのでしょうか?
(3)このsatoは(Student.new(“sato”))は、どのメソッドに渡されるのでしょうか?
(4)@nameのことはなんというのでしょうか?
(5)クラス内に書かれたこのメソッドは、なんというメソッドでしょうか?
(6)この記述(attr_accessor :name)では何を定義しているのでしょうか?
それでは動画を止めて考えてみてください。


class Student
    def initialize(name)
        @name = name 
    end 

    def avg(math, english)
        return (math + english) / 2
    end

    attr_accessor :name

end

a001 = Student.new("sato")
p a001.name,a001.avg(30,70)

それでは回答です。
initializメソッドは、オブジェクト生成をしたときに自動的に実行されるメソッドです。
Student.newではオブジェクトを生成しています。
satoはイニシャライズメソッドに値を渡しています。
@nameはインスタンス変数といいます。
クラス内に書かれたメソッドは、インスタンスメソッドといいます。
ここでは(attr_accessorのところ)ではアクセサを定義しています。これにより、オブジェクトの外からインスタンス変数を参照することができます。