スポンサーリンク

2015年5月17日

Rubyのクラス定義が分からない!!

タイトル:Rubyのクラス定義が分からない!!

目的:
Rubyにおけるクラス定義の仕方諸々が分からなかったので、
書き方などの基本をまとめテストコードを作成する。

実施環境:
OS:Windows8.1
Ruby:v2.2.2

ディレクトリ構造:
作業ディレクトリ
|-main1.rb
|-main2.rb
|-main3.rb
|-main4.rb

目次:

  1. クラス定義
  2. 継承の仕方
  3. モジュール定義
  4. その他


さて、掲示板を作成する前にふと気づいた。
あれ?...Rubyのクラスやメソッドの記述のどうやるんだ?...っと。
と言うわけなので、ちょっとまとめます。

1.クラス定義

1.1
クラスを定義してメソッドを記述した。
ソースコードは以下の通り作成した。
main1.rb
# encoding: utf-8
# File Name: main1.rb
# Create Day is 2015/05/17
# Last Update Day is 2015/05/17
# クラス
class TestClass
# 初期化関数
def initialize
puts "TestClass initialize!!"
end
def add(x, y)
puts x + y
end
end
puts "main1"
puts
test_class = TestClass.new
test_class.add(1, 2)
view raw main1.rb hosted with ❤ by GitHub


1.2
クラスの定義
class クラス名
end

メソッドの定義
def メソッド名(引数...)
  return 返り値
end

なお、initializeメソッドはデフォルトのインスタンスメソッドになる。

2.継承の仕方

クラスとは、メソッド群である...

2.1
スーパークラスとサブクラス、メソッドのオーバーライドについて記述した。
ソースコードは以下の通り作成した。
main2.rb
# encoding: utf-8
# File Name: main2.rb
# Create Day is 2015/05/17
# Last Update Day is 2015/05/17
# スーパークラス
class SuperClass
# 初期化関数
def initialize
puts "SuperClass initialize!!"
end
# 上書きするメソッド
def override_method
puts "SuperClass: override_method"
end
# 抽象メソッド
def abstract_method
raise "Called abstract method: abstract_method"
end
end
# サブクラス
class SubClass < SuperClass
# 初期化関数をオーバーライド
# スーパークラスの初期化関数を呼び出す
def initialize
super
puts "SubClass initialize!!"
end
# スーパークラスのメソッドをオーバーライド
def override_method
puts "SubClass: override_method"
end
# スーパークラスの抽象メソッドをオーバーライド
def abstract_method
puts "SubClass: abstract_method"
end
end
puts "main2"
puts
puts "SuperClass test"
super_class = SuperClass.new
super_class.override_method
puts
puts "SubClass test"
sub_class = SubClass.new
sub_class.override_method
sub_class.abstract_method
view raw main2.rb hosted with ❤ by GitHub


2.2
継承の仕方
class サブクラス名 < スーパークラス名
end

initializeメソッド内の「super」の記述は、
スーパークラスのinitializeを呼び出している。
引数を渡したいときは、「super(引数...)」で記述すればよい。

メソッドのオーバーライドの仕方は、
サブクラスにて、スーパークラスのメソッド(オーバーライド対象)と
同名のメソッドを定義する。

2.3
参考までに継承するものしないものを記述する。
サブクラスに継承するもの

  • インスタンスメソッド
  • クラスメソッド
  • クラス変数
  • 定数

サブクラスに継承されないもの

  • インスタンス変数
  • クラスインスタンス変数


3.モジュール定義

3.1
モジュールを定義し、それをインクルードしたクラスで利用している。
また、モジュールのメソッドをオーバーライドしている。
ソースコードは以下の通り。
main3.rb
# encoding: utf-8
# File Name: main3.rb
# Create Day is 2015/05/17
# Last Update Day is 2015/05/17
# モジュール
module ModuleTest
def test_method
puts "test1"
end
# モジュールで抽象メソッド
def abstract_test_method
raise "Called abstract method: abstract_test_method"
end
end
# モジュールをインクルードしたクラス
class ModuleIncludeClass
# Moduleをインクルード
include ModuleTest
# ModuleClassの抽象メソッド(abstract_test_method)をオーバーライド
def abstract_test_method
puts "ModuleIncludeClass: abstract_test_method"
end
end
puts "main3"
puts
test_module_include = ModuleIncludeClass.new
test_module_include.test_method
test_module_include.abstract_test_method
view raw main3.rb hosted with ❤ by GitHub


3.2
モジュール定義
module モジュール名
end

モジュールのインクルード(mix-in)
class クラス名
  include 利用モジュール名
end

クラス間で「has-a」の関係を行いたいとき使う。

4.その他
2項目詰め込んだせいか...何故か一番ソースが大きい...。

4.1
アクセス制限とアクセッサ(セッター、ゲッター)について記述した。
ソースコードは以下の通り。
main4.rb
# encoding: utf-8
# File Name: main4.rb
# Create Day is 2015/05/17
# Last Update Day is 2015/05/17
# その他
class SuperOther
def initialize(private_text="private", protected_text="protected", public_text="public")
@private_text = private_text
@protected_text = protected_text
@public_text = public_text
end
# プライベートメソッド(定義クラス内のみ公開)
private
def private_method
puts "private_method"
end
# プロテクテッドメソッド(定義クラスとそのサブクラスに公開)
protected
def protected_method
puts "protected_method"
end
# パブリックメソッド(クラスの外へも公開)
public
def public_method
puts "public_method"
end
def print_text
puts "@private_text is " + @private_text
puts "@protected_text is " + @protected_text
puts "@public_text is " + @public_text
end
# アクセッサ
private
# クラス内のみ公開
attr_accessor :private_text
protected
# 定義クラスとサブクラスのみ公開
attr_accessor :protected_text
public
# クラスの外に公開
attr_accessor :public_text
end
class SubOther < SuperOther
def initialize()
super("hoge", "huge", "hogehoge")
end
# 子クラスでプロテクテッドのメソッドを呼び出す
def call_protected_method
self.protected_method
end
# アクセッサで定義されている変数に値を入れる
def set_blank_text
self.private_text = ""
self.protected_text = ""
self.public_text = ""
end
end
puts "main4"
puts
puts "SuperOther test"
super_other = SuperOther.new
# privateは呼び出せない
#super_other.private_method
# protectedは呼び出せない
#super_other.protected_method
# publicは呼び出せる
super_other.public_method
super_other.print_text
puts
puts "SubOhter test"
sub_other = SubOther.new
sub_other.public_method
sub_other.call_protected_method
puts
sub_other.print_text
sub_other.set_blank_text
sub_other.print_text
view raw main4.rb hosted with ❤ by GitHub


4.2
アクセス制限には、3種類ある。

  • private: 定義したクラス内でのみ使用可能
  • protected: 定義したクラスとサブクラス内でのみ使用可能
  • public: 定義したクラス内でも外でも使用可能


アクセッサについて
アクセッサは、インスタンス変数に対してのセッター、ゲッターを提供する。

2.2で継承しないものに「インスタンス変数」が入っている。
なのに何故、サブクラスで親で定義した変数が参照できるのか?
アクセッサを利用しているため。

継承のための詳しい内容はこちらを参考にして頂くと分かり易いと思います。
お気楽 Ruby プログラミング入門 第 11 回 継承

以上!!

参考にさせて頂いたサイト
RubyLife - initializeメソッド
徒然なるままに - Rubyの継承についてのはなし(インスタンス変数,クラス変数,クラスインスタンス変数,インスタンスメソッド,クラスメソッド,定数)
attr_accessor (Module)
Qiita - Ruby | Ruby の private と protected 。歴史と使い分け

管理人の独り言...
本日は、データアクセスメソッド(DAM)パターンをやろうと思いました。
RubyGemsにActiveRecordがあるので必要ないと思い、
急遽方向転換し掲示板作成に取り掛かるが、結局Rubyの記述方法が分からないことに気付く。
仕方がないので、Ruby言語自体の基礎をやることと相成りました。
来週中には、掲示板の記事を上げていけると思います。

備忘メモ:Rubyでは、変数は代入をしないと存在しない。

人気の投稿