LoginSignup
1
1

More than 5 years have passed since last update.

Ruby クラス、インスタンス、継承

Posted at

動作環境はMacです。

クラス

クラスとは車でいえば設計図のこと。
インスタンスは、設計図を元に作られる自動車そのもの。
ゆえにクラスの要素はもつが、個々のインスタンスでの特徴は違う。

オリジナルクラスの作成

構文

class クラス名
end

**実践**

car.rb

class Car #Carクラスを作成。頭文字は大文字
  def hello #メソッドの定義
    puts "Hello!"
  end
end

car = Car.new  #newメソッドでインスタンスを生成し、変数carに格納
car.hello #インスタンス変数の呼び出し
cae.rb
class Car
  def initialize(name) #インスタンスが作成(new)されると同時に実行
        puts "初期化されました"
    @name = name #インスタンス変数に引数nameの値を格納
  end

  def hello
    puts "Hello! I am #{@name}" #インスタンス変数はインスタンスの中であればどこからでも参照可能
  end
end

car = Car.new("Kitt") #initializeされ、引数”Kitt”がnameに渡される
car.hello

karr = Car.new("Karr")
car.hello
car.rb
初期化されました #newされたタイミングで出力される
Hello! I am Kitt
初期化されました
Hello! I am Kitt

クラスに所有されるインスタンスであればいくらでも呼び出すことができる。

アクセサ(インスタンス)メソッド

ゲッター、セッターとも呼ばれる。
インスタンス変数はクラスの外部から呼び出すことができないため、
呼び出せるように設定するメソッド。

accessor.rb

class Car
  def initialize(name)
    puts "初期化されました"
    @name = name
  end

  def hello
    puts "Hello! I am #{@name}"
  end
end

car = Car.new("Kitt")
car.hello

car.@name #クラス外部からインスタンス変を呼び出す

出力結果

ruby accessor.rb
accessor.rb:15: syntax error, unexpected tIVAR, expecting '('
car.@name
         ^

エラーになる。

accessor.rb

class Car
  def initialize(name)
    puts "初期化されました"
    @name = name
  end

  def hello
    puts "Hello! I am #{@name}"
  end

  def name #外部から読み取り可能なメソッドを定義
    @name
  end
end

car = Car.new("Kitt")
car.hello

puts car.name #呼び出し

出力結果

ruby accessor.rb
初期化されました
Hello! I am Kitt
Kitt #呼び出された
accessor.rb

class Car
  def initialize(name)
    puts "初期化されました"
    @name = name
  end

  def hello
    puts "Hello! I am #{@name}"
  end

  def name
    @name
  end

  def name=(value) #nameのを書き換えるメソッド。=も含まれる。スペースは開けない
    @name = value #インスタンス変数にvalueを代入
  end

end

car = Car.new("Kitt")
car.hello

puts car.name
car.name = "sisido" #nameを書き換え
puts car.name

出力結果

初期化されました
Hello! I am Kitt
Kitt
sisido #書き換わった!

アクセサメソッド2

attr_accessor

インスタンスメソッドを簡単に書き込みや読み込みができるようにするためのメソッド

accessor.rb
def name
  @name
end

def name=(value)
  @name = value
end

#この記述を簡単に書き換える

accessor.rb
class Car

  attr_accessor :name #この箇所にアクセサメソッドを記述

  def initialize(name)
    puts "初期化されました"
    @name = name
  end

  def hello
    puts "Hello! I am #{@name}"
  end


  #def name
    #@name
  #end

  #def name=(value)
    #@name = value
  #end

end

car = Car.new("Kitt")
car.hello

puts car.name
car.name = "sisido"
puts car.name

出力結果

初期化されました
Hello! I am Kitt
Kitt
sisido

読み取り専用メソッド

accessor.rb
class Car

  #attr_accessor :name
  attr_reader :name #読み取り専用のメソッド

  def initialize(name)
    #puts "初期化されました"
    @name = name
  end

  def hello
    puts "Hello! I am #{@name}"
  end

  #def name
    #@name
  #end

  #def name=(value)
    #@name = value
  #end

end

car = Car.new("Kitt")
#car.hello
#car.@name NG

puts car.name
#car.@name = "sisido" NG
#car.name = "sisido"
puts car.name
Kitt
Kitt

書き込み専用のメソッド

attr_accessor.rb

class Car

  #attr_accessor :name
  #attr_reader :name
  attr_writer :name #書き込み専用メソッドの記述

  def initialize(name)
    #puts "初期化されました"
    @name = name
  end

  def hello
    puts "Hello! I am #{@name}"
  end

  #def name
    #@name
  #end

  #def name=(value)
    #@name = value
  #end

end

car = Car.new("Kitt")
#car.hello
#car.@name NG

#puts car.name
#car.@name = "sisido" NG
car.name = "sisido" 
#puts car.name

クラス変数

クラス自体に値を保持することができる変数

実践

class_val.rb

class Car
  @@counter = 0 #クラス変数はここに記述
  def initialize(name)
    @name = name
    @@counter += 1 #インスタンスが作成されるごとにインクリメントされる
  end

  def hello
    puts "Hello! I am #{@name}.#{@@counter} instanse(s)."#この中にインスタンスの作成回数を記録
  end
end

kitt = Car.new("Kitt")
kitt.hello

karr = Car.new("Karr")
karr.hello

imawano = Car.new("imawano")
imawano.hello

出力結果

Hello! I am Kitt.1 instanse(s).
Hello! I am Karr.2 instanse(s).
Hello! I am imawano.3 instanse(s).

クラスメソッド

クラスから直接呼び出すことができるメソッド

実践

class_val.rb

class Car
  @@counter = 0
  def initialize(name)
    @name = name
    @@counter += 1
  end

  def hello
    puts "Hello! I am #{@name}.#{@@counter} instanse(s)."
  end

  def self.info #クラスメソッドの作成 selfをつける
    puts "#{@@counter} instance(s)"
  end
end

#kitt = Car.new("Kitt")
#kitt.hello

#karr = Car.new("Karr")
#karr.hello

#imawano = Car.new("imawano")
#imawano.hello

Car.info #クラスメソッドの呼び出し

出力結果

0 instance(s) #インスタンスは作成していないため0

インスタンスが作成された直後にクラスメソッドを呼び出す

class_val.rb
class Car
  @@counter = 0
  def initialize(name)
    @name = name
    @@counter += 1
  end

  def hello
    puts "Hello! I am #{@name}.#{@@counter} instanse(s)."
  end

  def self.info
    puts "#{@@counter} instance(s)"
  end
end

kitt = Car.new("Kitt")
#kitt.hello
Car.info

karr = Car.new("Karr")
#karr.hello
Car.info

imawano = Car.new("imawano")
#imawano.hello
Car.info

出力結果


1 instance(s)
2 instance(s)
3 instance(s)

1つのクラスをインスタンスが共通して使用していることがわかる。

クラスと定数

class_const.rb
class Car
  REGION = "USA" #定数の定義
  @@counter = 0
  def initialize(name)
    @name = name
    @@counter += 1
  end

  def hello
    puts "Hello! I am #{@name}.#{@@counter} instanse(s)."
  end

  def self.info
    puts "#{@@counter} instance(s). REGION: #{REGION}" ##クラスメソッド内で定数を使用
  end
end

kitt = Car.new("Kitt")
#kitt.hello
Car.info

karr = Car.new("Karr")
#karr.hello
Car.info

imawano = Car.new("imawano")
#imawano.hello
Car.info

puts Car::REGION #定数の呼び出し

定数の作成や呼び出しはクラス変数やインスタンス変数と違うので注意

**クラスの継承**

スーパークラス(親クラス)の振る舞いをサブクラス(子クラス)でも使用することができる

**実践**

sub_class.rb
class User
  def initialize(name)
    @name = name
  end

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

class AdminUser < User #Userクラスの継承
  def admin_hello #AdminUserクラス内でメソッドを定義
    puts "Hello! I am #{@name} from AdminUser."
  end
end

iwamano = User.new("iwamano")
iwamano.hello

sansiro = AdminUser.new("sansiro") 
sansiro.hello #AdminUserクラスのでUserクラスのメソッドを使用
sansiro.admin_hello #AdminUserクラス内のメソッドを使用

出力結果

Hello! I am iwamano.
Hello! I am sansiro.
Hello! I am sansiro from AdminUser.

Userクラス(親クラス)からAdminUserクラスのメソッドを呼び出すことはできない

sub_class.rb

iwamano = User.new("iwamano")
iwamano.hello
iwawano.admin_hello

出力結果

Hello! I am iwamano.
sub_class.rb:19:in `<main>': undefined method `admin_hello' for #<User:0x007fbc6a19f4c8 @name="iwamano"> (NoMethodError) #エラーが返る

オーバーライド

親クラスの持つ振る舞いを子クラスで上書きや追加をすることができる機能

実践

sub_class.rb

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

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

class AdminUser < User
  def admin_hello
    puts "Hello! I am #{@name} from AdminUser."
  end

  def hello
    puts "Admin!" #親クラスのhelloメソッドに上書き
  end
end

iwamano = User.new("iwamano")
iwamano.hello #子クラスのhelloメソッドの呼び出し
#iwamano.admin_hello

sansiro = AdminUser.new("sansiro")
sansiro.hello
sansiro.admin_hello

出力結果

Hello! I am iwamano.
Admin! #親クラスのhelloメソッドは呼び出されず、子クラスのhelloメソッドが呼び出されている
Hello! I am sansiro from AdminUser.

オーバーライドは親クラスの修正を加えることなく子クラスに同名のメソッドを記述することで、上書きや追加をすることができる。

クラスの確認

クラス名.superclassで確認することができる。

例)Integerクラス

irb(main):002:0> Integer.superclass
=> Numeric
irb(main):003:0> Numeric.superclass
=> Object
irb(main):004:0> Object.superclass
=> BasicObject
irb(main):006:0> BasicObject.superclass
=> nil #BasicObjectクラスが大元の親クラスとなるため、nilが返る
1
1
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
1
1