Ruby クラス②
クラスメソッド、クラス変数
クラスメソッド、クラス変数
クラスメソッド
- クラスから直接呼ぶことができるメソッド
クラス変数
- クラス自体に値を保持することができる変数
サンプルコード
class User
REASION = 'USA'
@@count = 0
def initialize(name)
@name = name
@@count += 1
end
def hello
puts "I am #{@name}. #{@@count} instance(s)."
end
def self.info
puts "#{@@count} instance(s).Reasion: #{REASION}"
end
end
emma = User.new('Emma')
#emma.hello
User.info
olivia = User.new('Olivia')
#olivia.hello
User.info
mary = User.new('Mary')
#mary.hello
User.info
puts User::REASION
👇
クラス変数は@@で始まる!
@@count = 0
initializeメソッドにも記述
initializeメソッドが呼ばれた回数
(インスタンスが作成された回数)をカウントする
def initialize(name)
@name = name
@@count += 1
end
そして、helloメソッドの中で出力
def hello
puts "I am #{@name}. #{@@count} instance(s)."
end
このように表示される
I am Emma. 1 instance(s).
I am Olivia. 2 instance(s).
I am Mary. 3 instance(s).
インスタンスを生成するために
このクラス変数の@@countがインクリメントされて
123というようになっている
次にクラスメソッドを定義する
クラスメソッドにはselfをつける
def self.info
puts "#{@@count} instance(s)."
end
クラスメソッドはクラスから直接呼ぶことができる
インスタンスを作成しなくても
User.info
とすればクラスメソッドを呼び出すことができる
クラスで定数を定義する方法
慣習で定数名は大文字で書く
REASION = 'USA'
この定数をクラスメソッドで引用してみる
def self.info
puts "#{@@count} instance(s).Reasion: #{REASION}"
end
実行するとこのように出力されている
1 instance(s).Reasion: USA
2 instance(s).Reasion: USA
3 instance(s).Reasion: USA
定数はクラスの外からアクセスすることもできる
その場合このように記述する
puts User::REASION
REASIONに入っている定数USAが出力された
1 instance(s).Reasion: USA
2 instance(s).Reasion: USA
3 instance(s).Reasion: USA
USA
クラスの継承
クラスの継承
- 親クラス(スーパークラス)の機能を引き継いで、子クラス(サブクラス)を作成することができる。
- コードの再利用性や拡張性を高める仕組み
例)
【親】自動車クラス(タイヤ、エンジン、ブレーキ)
- 【子】戦車クラス(+大砲)
- 【子】乗用車クラス(+後部座席)
- 【子】トラック(+荷台)
サンプルコード
class User
def initialize(name)
@name = name
end
def hello
puts "Hello! I am #{@name}"
end
end
nakamura = User.new('Nakamura')
nakamura.hello
class AdminUser < User
def hello_admin
puts "Hello! I am #{@name} form AdminUser."
end
def hello
puts 'Admin!!'
end
end
sato = AdminUser.new('Sato')
sato.hello
sato.hello_admin
👇
ユーザークラスを継承して、
Adminユーザークラス(管理者用のクラス)を作る
記述の仕方
class 子クラスの名前 < 親クラスのクラス名
class AdminUser < User
end
これでAdminユーザークラスはユーザークラスが持っている
インスタンス変数@nameやインスタンスメソッドhelloを利用できる
用語としてUserクラスの方を親クラス、またはスーパークラス
AdminUserクラスの方を子クラス、またはサブクラスと呼ぶ
AdminUserクラスの方にAdminUser専用のメソッドを書いてみる
(Userクラスに変更を加えずにAdminUser用の処理を追加できる)
class AdminUser < User
def hello_admin
puts "Hello! I am #{@name} form AdminUser."
end
hello_adminメソッドをよび実行
sato.hello_admin
このように呼び出すことができる
Hello! I am Nakamura
Hello! I am Sato
Hello! I am Sato form AdminUser.
メソッドのオーバーライド
子クラスの方で親クラスの同じ名前のメソッドを上書きする方法
親クラスのhelloメソッドをAdminユーザーの方で
オーバーライドしてみる
def hello
puts 'Admin!!'
end
親クラスのhelloメソッドではなく
子クラスでオーバーライドしたhelloメソッドの方が呼ばれた
Admin!
メソッドのアクセス権
メソッドのアクセス権
- メソッドにアクセスできる条件を指定できる
3つの種類がある
- public
クラスの外部からでも自由に呼び出せる(デフォルト) - protected
(※あまり使わないので今は省略) - private
クラスの外からは呼び出せず、クラス内部でのみ使えるメソッド
サンプルコード
class User
def initialize(name)
@name = name
end
private
def hello
puts "Hello! I am #{@name}."
end
end
user = User.new('Nakamura')
user.hello
アクセス権を何も指定しない場合はpublicの指定となる
initializeメソッドは特別なメソッドなのでこの条件からは外れる
privateの指定をする
helloメソッドのアクセス権をprivateにするには
privateと上に書く
private
def hello
puts "Hello! I am #{@name}."
end
privateと書いた行よりも下に書いたメソッドは
アクセス権がpraivateになる
出力しても
NoMethodErrorとなる
モジュール
モジュール
クラスのようにメソッドや定数をまとめられるもの
クラスとの違い
- インスタンスを作ることができない
- 継承ができない
モジュールの定義
module モジュール名
# モジュールの定義(メソッドや、定数など)
end
関連するメソッドや定数などをまとめてグループ化したいだけのときに
モジュールは手軽に使えて便利!
サンプルコード
module Driver
def self.run
puts 'Run'
end
def self.stop
puts 'Stop'
end
end
Driver.run
Driver.stop
インスタンスメソッドは作れないのでselfをつける
このようにメソッドを呼び出して出力できた
Run
Stop
#NG
#インスタンス化できない
driver = Driver.new
#継承もできない
module TaxiDriver < Driver
end
エラーになる
例外
例外(Exception)
プログラムの実行中に発生した「例外」的な問題
例外処理
例外が発生したときに、それをキャッチして、ユーザーにメッセージを表示するなど
何らかの処理を行うこと
数値を0で割った時の例外をキャッチして
例外処理としてエラーメッセージを出力するプログラムを書いてみる
今回はターミナルから数値を入力させるプログラムも書く
サンプルコード
puts '---数値を入力してださい---'
i = gets.to_i
begin
# 例外が起きうる処理
puts 10 / i
rescue => ex
# 例外が発生した場合の処理
puts 'error!'
puts ex.message
puts ex.class
ensure
# 例外が発生しても、しなくても、最後に実行したい処理
puts 'end'
end
getsでターミナルに入力された文字列を取得できる
i = gets.to_i
その文字列をto_iメソッドで数値に変換
それを変数iに入れる
例外が起きうる処理
実行したい処理は
puts 10 / i
iに0が入った時は0除算となり、例外が発生する!!
例外処理を書くにはまずbeginとし、最後はend
beginの直下には例外が起きうる処理を書く
次にrescueを利用
rescue => ex
例外が発生した場合の処理を書く
puts 'error!'
puts ex.message
puts ex.class
ensure
入力したユーザーにエラーを伝える puts 'error!'
エラーの内容が何なのか出力 puts ex.message
例外のオブジェクトのクラス名を知りたいとき puts ex.class
最後に ensure
例外が発生しても、しなくても、最後に実行したい処理を書く
puts 'end'
実行
10/2で5が出力された
ensureの処理でendも出力された
---数値を入力してださい---
2
5
end
エラーの場合
0
error!
divided by 0
ZeroDivisionError
end
エラーの内容
divided by 0 = 0で割ったのでエラーになっている
ZeroDivisionError = というクラス
最後にensure = end
実務では、このように例外が発生した場合の記述が大事になってくる!!
Rubyのコーディングルール(コーディング規約)
- Rubyの公式のコーディングルールは存在しない(2017年1月現在)
- 「The Ruby Style Guide」が有名
- 参考:Rubyのソースコード解析ツールRuboCopの作者と同じ
https://github.com/rubocop/rubocop
「リンク」
英語
日本語訳
ここに書かれていることを全て守らなくてはいけないということではないが
プロジェクトチームで開発を行うときは
このコーディングルールをベースとして開発を行うと良い!
分量が多いので全てを覚えて確認をするのは大変
そこで同じ作者がRuboCopという
ソースコードを解析するツールを公開している
これを使うと開発したコードが自動でコーディングルールに
乗っ取っているか確認してくれる😃
Ruby一旦講座の範囲は終わり!!
明日からMySQL入る!
パワー
Discussion