よしかわーるど

プログラミングで世界を変える

2018-09-25

Rubyを学ぶ 5 日目

前回の記事

Ruby を学ぶ 4 日目

クラスとモジュール

オブジェクト指向スクリプト言語の特徴をつかむために学んでいきます。

クラス

クラスはオブジェクトの種類を表す。 同じクラスのオブジェクトは同じメソッドを受け付ける。クラスはオブジェクトの振る舞いを決める。 クラスは物体(オブジェクト)を作成する元になる設計図。

継承

すでに定義されているクラスを拡張して新しいクラスを作ることを継承とよぶ。

「時計クラス」から「アナログ時計クラス」と「デジタル時計クラス」を継承する。

継承によって作られたクラスを サブクラス 、継承のもとになったクラスを スーパークラス という。

  • 既存の機能はそのままで、まったく新しい機能を追加
  • 既存の機能を定義し直して同じ名前のメソッドに違う振る舞いをさせる
  • 既存の機能に処理を追加して拡張する

サブクラス

サブクラスはスーパークラスのインスタンスメソッド、クラスメソッドは継承するがインスタンス変数の情報が持たない。 インスタンスメソッド内で定義されているものは結果的に引き継ぐことになる。 定数も引き継ぐ。サブクラスで定数を定義した場合は上書きされる。

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 ClassName
  puts "this is test"
end

クラス名は必ず最初は 大文字

initialize メソッド

class 文の中でメソッドを定義すると、そのクラスのインスタンスメソッドになる。ただし、initialize メソッドは特別。new メソッドによってオブジェクトを生成すると、このメソッドが呼ばれる。 オブジェクトによって必要な初期化の処理はここに記述。

def initialize(myname="Ruby")
  @name = myname # インスタンス変数の初期化
end

initialize メソッドは引数 myname を受け取るようになっている。 bob = HelloWorld.new("Bob") というようにして、オブジェクトの生成をすると、initialize メソッドに”Bob”が渡される。ただし、initialize メソッドは引数にデフォルト値”taiki”が指定されているから ruby = HelloWorld.new というように引数を渡されなかった場合は、自動的に”Ruby”が渡される。

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

@name = mynameによって、引数で渡されたオブジェクトを@name という変数に代入している。@で始まる変数は インスタンス変数 という。ローカル変数はメソッドごとに異なる変数として扱われるが、インスタンス変数は同じインスタンス内であればメソッド定義を超えて、その値を参照したり、変更したり出来る。なお、初期化されていないインスタンス変数を参照すると、’nil’が得られる。

アクセスメソッド

Ruby では、オブジェクトの外部からインスタンス変数を直接参照したり、インスタンス変数に代入することが出来ない。オブジェクトの内部の情報にアクセスするには、そのためのメソッドを定義する必要がある。

定義 意味
attr_render :name 参照のみ可能にする(name メソッドを定義する)
attr_writer :name 変更のみ可能にする(name=メソッドを定義する)
attr_accessor :name 参照と変更を可能にする(上記 2 つを定義する)

self

インスタンスメソッドの中で、メソッドのレシーバ自身を参照するには self という特別な変数を使う。

クラスメソッド

クラスメソッドはクラスそのものをレシーバとするメソッド。クラスメソッドはclass << クラス名 ~ endという特別なクラス定義の中にインスタンスメソッドの形式で定義。 def クラス名.メソッド名 ~ endの形式でクラスメソッドを定義することもできる。 「class << クラス名 ~ end」という書き方のクラス定義を 得意クラス定義 という。また、得意クラス定義で定義したメソッドを 得意メソッド という。

定数

class 文の中では定数を定義できる。

class HelloWorld
  Version = "1.0"
end

クラスの持っている定数は、次のように「::」を使ってクラス名を経由すればクラスの外部からも参照可能。 p HelloWorld::Version #=> "1.0"

クラス変数

「@@」で始まる変数はクラス変数。クラス変数とは、そのクラスの全てのインスタンスで共有できる変数。クラス変数は定数と違って、何度でも変更することが出来る。また、クラスの外部からクラス変数を参照するには、インスタンス変数の場合と同様にアクセスメソッドが必要。’attr_accessor’などは使えないので直接定義する必要がある。

参考資料

クラス/メソッドの定義 (Ruby 2.5.0)