動作環境はMacです。
クラス##
クラスとは車でいえば設計図のこと。
インスタンスは、設計図を元に作られる自動車そのもの。
ゆえにクラスの要素はもつが、個々のインスタンスでの特徴は違う。
オリジナルクラスの作成
構文
class クラス名
end
**実践**
class Car #Carクラスを作成。頭文字は大文字
def hello #メソッドの定義
puts "Hello!"
end
end
car = Car.new #newメソッドでインスタンスを生成し、変数carに格納
car.hello #インスタンス変数の呼び出し
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
初期化されました #newされたタイミングで出力される
Hello! I am Kitt
初期化されました
Hello! I am Kitt
クラスに所有されるインスタンスであればいくらでも呼び出すことができる。
アクセサ(インスタンス)メソッド
ゲッター、セッターとも呼ばれる。
インスタンス変数はクラスの外部から呼び出すことができないため、
呼び出せるように設定するメソッド。
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
^
エラーになる。
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 #呼び出された
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
インスタンスメソッドを簡単に書き込みや読み込みができるようにするためのメソッド
def name
@name
end
def name=(value)
@name = value
end
# この記述を簡単に書き換える
↓
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
読み取り専用メソッド
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
書き込み専用のメソッド
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 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 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 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 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 #定数の呼び出し
定数の作成や呼び出しはクラス変数やインスタンス変数と違うので注意
**クラスの継承**
スーパークラス(親クラス)の振る舞いをサブクラス(子クラス)でも使用することができる
**実践**
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クラスのメソッドを呼び出すことはできない
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) #エラーが返る
オーバーライド
親クラスの持つ振る舞いを子クラスで上書きや追加をすることができる機能
実践
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が返る