楽しいRuby 第8章


クラスとモジュール

ここまでの説明で、
どんなプログラムでも必要となる基本的なデータ型(数値,文字列,配列,ハッシュ)
データを操作するための道具であるメソッド
プログラミングの流れを記述するための制御構造を紹介しました。
これは大抵のプログラミング言語で共通の考えかたで、ある意味プログラミングの基本とも言えるものです。

#オブジェクト指向の共通の概念と道具「クラス」「モジュール」

-クラス オブジェクト指向の共通概念である「クラス」
-モジュール Rubyの特徴的な機能をもつ道具



 ##クラスとは
 オブジェクト指向のおけるクラスとは？？
 
 「クラスとはオブジェクトの種類を表す」
 
 Rubyのオブジェクトは例外なく何らかのクラスに属しています。
 
 「Rubyの全てのクラスは"BasicObject"クラスのサブクラスとなります」
 
 例
 「配列オブジェクト」や単に「配列」と呼んできたオブジェクトは実際は「Arrayクラスのオブジェクト」です。
 
 そして同じクラスのオブジェクト同じメソッドを受け付けます。
 クラスはオブジェクトの振る舞いを決める役割を持ちます。
 
 
 ##継承
 
 「すでの定義されているクラスを拡張して新しいクラスを作ることを"継承"と言います」
 
スーパークラス　継承に元となったクラス
サブクラス 継承によって作られた新しいクラス

継承によってできること
-既存の機能はそのままで、全く新しい機能を追加する
-既存の機能を定義し直して同じ名前のメソッドに違う"振る舞い"をさせる
-既存の機能に処理を追加して拡張する
 
 
 - Task
 画面上に時計を表示するクラスを作ってみましょう。
 このクラスはユーザーの好みに応じて「アナログ時計」や「デジタル時計」のような表示にしたりできることにします。

仕様
-時間を表示する形式
-現在時刻を取得する方法
-アラームなどの基本的な仕事


このことから
「基本的な機能をもった"時計クラス"」
「アナログ時計クラス」
「デジタル時計クラス」を継承するという方式をとります。


##クラスを作る

hello_class.rb


```   
class HelloWorld     #class文
  def initialize(myname = "Ruby")　#initializeメソッド
    @name = myname　　　#インスタンス変数の初期化
  end


  def hello
    puts "Hello, world. I am #{@name}"
  end
end

bob = HelloWorld.new("Bob")
alice = HelloWorld.new("Alice")
ruby = HelloWorld.new

bob.hello  


```

-class文
クラスの定義にはclass文を使います。
class文の一般的な構文

class クラス名(先頭文字を大文字にする)
  クラスの定義
end 

-initializeメソッド
initialize メソッドは、オブジェクト（事前に定義したクラスのインスタンス）の初期化のためのメソッドです。 クラスに対して new メソッドを呼び出すと、 new メソッドはインスタンスを作成し、そのインスタンスに対して initialize を呼び出します。 new に渡した引数は、そのまま initialize に渡されます。 なお、 initialize の戻り値は使われません。


以下 class HelloWorld(スーパークラス)の説明

```

class HelloWorld
  def initialize(myname = "Ruby")
    @name = myname
  end

  def hello
    puts "Hello, world. I am #{@name}"
  end
end


ruby = HelloWorld.new
bob = HelloWorld.new("Bob")
alice = HelloWorld.new("Alice")

ruby.hello
bob.hello
alice.hello

```

=begin

「initializeメソッドの機能
1,newメソッドによってオブジェクト(インスタンス)が生成された時にこのメソッドが呼ばれます。」

2,initializeメソッドには引数mynameに初期値 "Ruby"が指定されているので、
-mynameに"Ruby"が代入される
-インスタンス変数""@name"にmynameが代入される
という処理が行われています。

3,ruby = HelloWorld.newによってHelloWorldクラスのインスタンス "ruby"が生成された時に
initializeメソッドが呼び出されます。

この時、newメソッドに引数を渡していないので、"@name"には"Ruby"が渡されます
また、オブジェクトにとって必要な初期化の処理はここに記述します。

4,"HelloWorld"クラス(スーパークラス)のサブクラスであるためインスタンス"ruby"は
"HelloWorld"クラスのメソッドを扱えます。

なので、インスタンス"ruby"でhelooメソッドを使ったみましょう

ruby.hello

結果

Hello, world. I am Rubyと表示されます。

このとき
"@name"にはinitializeメソッドで引数として与えられている"Ruby"が代入されているので
Hello, world. I am Rubyと表示されるわけです。


ではinitializeメソッドの引数"myname"にほかの値を代入するにはどうしたらいいのでしょうか？？


それはinitializeメソッドの機能を利用します

initializeメソッドは
newメソッドによってインスタンスを生成することでinitializeメソッド自身が呼ばれる機能を
持っています。
その時、newメソッドに渡した引数がそのままinitializeメソッドに渡されるのです、


例を出しましょう

def initialize(myname = "Ruby")
  @name = myname
end

この時、initializeメソッドには"Ruby"が代入されています

それではbob = HelloWorld.new("Bob")と記述してみましょう

initializeメソッドの機能によってnewメソッドがインスタンスを生成するとinitializeメソッド
も呼び出されます、その時、initializeメソッドに対して"newメソッド"に渡した引数がそのまま
渡されます

つまり

def initialize(myname = "Bob")
  @name = myname
end

となるわけです。

=end



##インスタンス変数とインスタンメソッド


```
def initialize(myname = "Ruby")
  @name = nyname
end  
```

-インスタンスメソッド
メソッドは『メソッド』で見たとおり実行する一連の処理をまとめたものです。ただし通常のメソッドがプログラム中からいつでも呼び出せるのに対してクラス内に記述されたメソッドはクラスから作成されたオブジェクトしか呼び出すことが出来ません。このようなメソッドをインスタンスメソッドと呼びます。

-インスタンス変数@nameは、「同じインスタンス内であればメソッド定義を超えてその値を参照したり、変更したりできます」

-なお初期化されていないインスタンス変数を参照すると"nil"が得られます。
-インスタンス変数は,"インスタンスごとに違う値を持つことができます"
-インスタンス変数は、インスタンスが存在している間は値を保持しておいて何度でも
利用できます

例えば、

```
alice = HelloWorld.new("Alice")
bob =  HelloWorld.new("Bob")
ruby = HelloWorld.new

```
とすると、"alice"と"bob"と"ruby"は「それぞれ異なる@name」持ちます 


　　　　　　　　　　　HelloWorldクラス
　　                    
　　　|new("Bob")             |new("Alice")                  |new　　　
　　　                             　　　　　　　         
 @name = "Bob"    @name = "Alice"          @name = "Ruby"