0
0

Rubyのクラスを理解する

Last updated at Posted at 2023-12-23

Rubyのクラスを理解する

目次

1.基本知識の確認

1-1.メソッド
1-2.引数
1-3.クラス
1-4.インスタンス

2.クラスで使う呪文達

2-1.インストラクタ(intializeメソッド)
2-2.インスタンス変数(@<変数名>)
2-3.ゲッターとセッター(attr_accessor)
2-4.特殊キーワード(self)

基本知識の確認

クラスの説明をする前に、まずはクラスの中身を説明するために必要な
基本的な単語や知識について記載します。

1-1.メソッド

概要
一言で言うと「関数」のこと、Rubyでは「メソッド」と呼びます。
具体的には実行したい処理をまとめたもの。
クラスメソッドとインスタンスメソッドなどがある。

記述方法
「def」と「end」を書いて、実行したい処理は間に書きます
その後、関数名(defの後に書いた名前)を記述して呼び出し

具体例
メソッド名「hello」、処理は「こんにちは」と出力する関数

メソッド具体例
def hello
  puts "こんにちは"
end

hello

1-2.引数

概要
まずは読み方ですが、引数(ひきすう)と呼びます
具体的には関数などにに、渡す値のことを言います

記述方法
メソッドの後に()をつけて、()内に引数を入れます

具体例
メソッド名「hello」、処理は「こんにちは」と出力する関数
引数に山田を選択して、山田さん、こんにちはと出力させる

引数
def hello(name)
  puts "#{name}さん、こんにちは"
end

hello("山田")

1-3.クラス

概要
オブジェクトの設計図となるもの
具体的にはメソッドや変数を定義してまとめたもの
※設計図なので、クラスを作っただけでは実際に処理はできない。
 →こんな処理できたらいいよなーって妄想してるだけの状態

記述方法
「class」と「end」で囲む

具体例
クラス名「Greeting」、処理は朝・昼・晩の挨拶を出力する関数

クラス
class Greeting
  def morning
    puts "おはよう"
  end

  def afternoon
    puts "こんにちは"
  end

  def
    puts "こんばんは"
  end
end

1-4.インスタンス

概要
クラスを形にしたもの
クラスからインスタンスを生成することで初めて実体になる
イメージとしては妄想を現実にして作ってみたーって感じ

記述方法
クラスを書いた上で、下記のように記載してインスタンスを生成する
→<インスタンス名>=<クラス名>.new
インスタンスにして関数を呼び出すには
→<インスタンス名>.<関数名>

具体例
Greetingクラスを定義する
sampleという名前のインスタンスを生成する

インスタンス
class Greeting
  def morning
    puts "おはよう"
  end
end

sample = Greeting.new #ここでインスタンスを生成
sample.morning         #関数を呼び出し

⒉クラス内の呪文達

2-1.コンストラクタ

概要
クラスをインスタンス生成した際に最初に起こる処理
→初期に登録したい固有の状態を登録できる

記述方法
initializeメソッドを使用する

具体例
Greetingクラスにおいて、初期値として「山田」という名前を登録する

コンストラクタ(initializeメソッド)
class Greeting
  def initialize
    name = "山田"
  end

  def morning
    puts "#{name}さん、おはよう"
  end
end

sample = Greeting.new
sample.moring

以上のコードを書くことで「山田さん、おはよう」と出力される...
と思いきや実は出力されない
実はこのままだとエラーになる。理由は次で説明する


2−2.インスタンス変数

2種類の変数
実は変数には2種類ある。「ローカル変数」と「インスタンス変数」である
「ローカル変数」とは定義した関数でしか使用できない
「インスタンス変数」は他の関数でも使用できる

記述方法
記述方法はとても簡単
・ローカル変数  →<変数名>
・インスタンス変数→@<変数名>

具体例
先ほどのコードを修正する
(さっきのコードだとnameはinitializeメソッドのみでしか使用できないので
 moriningメソッドで使用するとエラーになる)

インスタンス変数
class Greeting
  def initialize
    @name = "山田"
  end

  def morning
    puts "#{@name}さん、おはよう"
  end
end

これでエラーがなく無事に「山田さん、おはよう」と出力されます。
次は引数を使って、山田さん以外の人でも処理できるようにしたいですね。


2-3. ゲッターとセッター

前提

・クラスを作る意味の1つにカプセル化という概念がある
・カプセル化は簡潔にいうと勝手にクラスの中身を取り出したり
 書き換えたりできなくすることである
・デフォルトではクラスの中の変数を取り出したり
 書き込んだりはできないようになっている。

ゲッター(getter)

概要
・クラス内に格納された値を取得するためのメソッド
・値を取得できるメソッド関連を総称してgetterと呼ぶ

具体例
nameというインスタンス変数を取得できるゲッターメソッド

getter
class Greeting
 definitialize(value)
   @name = value
 end
#ここからがgetterメソッド
  def name
    @name 
  end
#ここまで
end

sample = Greeting.new
sample.name

セッター(setter)

概要
・クラス内に格納されたインスタンス変数に値を書き込むメソッド
・値を書き込めるメソッドを総称してsetterと呼ぶ

具体例
nameというインスタンス変数を書き込めるセッターメソッド

setter
class Greeting
  def initialize(value)
    @name = value
#ここからがsetterメソッド
  def name=(value)
    @name = value
  end
#ここまで
end

sample =Greeting.new
sample.name("山田")

アクセサ

上記のように、クラス内の変数に処理するには外部アクセスを許可する記述が必要である。
ただ、毎回このように書くのは少し面倒である。
そこで省略できる画期的な記述がアクセサである(3種類あり)

#アクセサ一覧
  attr_reader   #getterと同様にインスタンス変数を取り出せる
  attr_writer   #setterと同様にインスタンス変数を設定できる
  attr_accessor #getterとsetterの両方の機能を兼ね備えている

先ほどのgetterとsetterは合わせて6行あるが、アクセサを使用すると以下のようになる

アクセサ
class Greeting
  attr_accessor :name
  def initialize(value)
    @name = value
  end
end

6行の記述が1行で済むので、使用するのはマストとも言える。
attr_accessorの1行でやっていることをあえて明示するとしたら
・インスタンス変数@nameを作成する
・getterメソッド(name)を定義する
・setterメソッド(name)を定義する

と言えると思う。最後のselfで混乱しないように上記のように機能を分解した。


2-4.selfについて

概要
結論から話すと、その書いているところそのもの(オブジェクト)
英語で言うとit的なニュアンスでその場その場で変わる厄介なもの。

具体例
・クラスメソッド内ではクラス
 ※クラスメソッド
  →インスタンス生成しなくても<クラス名>.<メソッド>で処理できる
   インスタンスに関わらず、固有の処理となる
・インスタンスメソッド内ではインスタンス
を表している具体例

selfの役割
class Greeting
  def self.class_method   #ここでのselfはクラス名Greetingとなる
   puts "クラスメソッドです"
  end
  attr_accessor :name
  def initialize(value)
    self.name = value      #ここではインスタンス名sampleとなる
  end
end

Greeting.class_method
sample =Greeting.new("山田")

selfはattr_acsessorとよく一緒に書かれている印象です。

よく使われるselfの使用パターン
class Greeting
  attr_accessor :name , :country

  def initialize(input_name,input_country)
    self.name = input_name
    @country = input_country
  end
end

sample = Greeting.new("山田", "日本")

この場合は丁寧に順序立てると
①attr_reader 
 →インスタンス変数@name@countryを定義
 それぞれname,countryという名前のgetterとsetterを定義
②self.name = name
 →setterメソッドのnameを呼び出して引数input_nameを代入
@country = input_country
 →インスタンス変数@countryに直接input_countを代入

結論
selfでも@でも今回の事例で言うとやっていることは同じ
代入の方法が異なる
・selfは関数を呼び出して代入している
・@はインスタンス変数に直接代入している

##まとめ
今回は説明を自分なりに分かりやすくするため変数を区別しました。
実際は引数とインスタンス変数の名前を一緒にして記述されている場合がほとんど。
コードの簡略化などの理由もあるが、初心者の混乱を招く原因の一つだと思う。
今後も自分なりに理解した内容を噛み砕いて記述していければと思う。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0