Ruby Language
クラス
サーチ…
構文
- クラス名
- クラスの動作を説明する#コード
- 終わり
備考
Rubyのクラス名は定数なので、最初の文字は大文字にする必要があります。
class Cat # correct
end
class dog # wrong, throws an error
end
クラスの作成
class
キーワードを使用して新しいクラスを定義することができます。
class MyClass
end
いったん定義されると、 .new
メソッドを使用して新しいインスタンスを作成できます
somevar = MyClass.new
# => #<MyClass:0x007fe2b8aa4a18>
コンストラクタ
クラスにはコンストラクタが1つしかない場合がありinitialize
。つまり、 initialize
というメソッドです。このメソッドは、クラスの新しいインスタンスが作成されると自動的に呼び出されます。
class Customer
def initialize(name)
@name = name.capitalize
end
end
sarah = Customer.new('sarah')
sarah.name #=> 'Sarah'
クラス変数とインスタンス変数
クラスがデータをより簡単に共有するために使用できる特殊な変数型がいくつかあります。
@
で始まるインスタンス変数。異なる変数で同じ変数を使いたい場合に便利です。
class Person
def initialize(name, age)
my_age = age # local variable, will be destroyed at end of constructor
@name = name # instance variable, is only destroyed when the object is
end
def some_method
puts "My name is #{@name}." # we can use @name with no problem
end
def another_method
puts "My age is #{my_age}." # this will not work!
end
end
mhmd = Person.new("Mark", 23)
mhmd.some_method #=> My name is Mark.
mhmd.another_method #=> throws an error
@@
前にあるクラス変数。クラスのすべてのインスタンスに渡って同じ値が格納されます。
class Person
@@persons_created = 0 # class variable, available to all objects of this class
def initialize(name)
@name = name
# modification of class variable persists across all objects of this class
@@persons_created += 1
end
def how_many_persons
puts "persons created so far: #{@@persons_created}"
end
end
mark = Person.new("Mark")
mark.how_many_persons #=> persons created so far: 1
helen = Person.new("Helen")
mark.how_many_persons #=> persons created so far: 2
helen.how_many_persons #=> persons created so far: 2
# you could either ask mark or helen
グローバル変数の前に$
が付いています。これらはプログラムのどこでも利用できますので、それらを賢明に使用してください。
$total_animals = 0
class Cat
def initialize
$total_animals += 1
end
end
class Dog
def initialize
$total_animals += 1
end
end
bob = Cat.new()
puts $total_animals #=> 1
fred = Dog.new()
puts $total_animals #=> 2
ゲッターとセッターでインスタンス変数にアクセスする
私たちには3つの方法があります:
-
attr_reader
:クラス外の変数のread
を許可するために使用されます。 -
attr_writer
:クラス外の変数の変更を許可するために使用されます。 -
attr_accessor
:両方のメソッドを結合します。
class Cat
attr_reader :age # you can read the age but you can never change it
attr_writer :name # you can change name but you are not allowed to read
attr_accessor :breed # you can both change the breed and read it
def initialize(name, breed)
@name = name
@breed = breed
@age = 2
end
def speak
puts "I'm #{@name} and I am a #{@breed} cat"
end
end
my_cat = Cat.new("Banjo", "birman")
# reading values:
my_cat.age #=> 2
my_cat.breed #=> "birman"
my_cat.name #=> Error
# changing values
my_cat.age = 3 #=> Error
my_cat.breed = "sphynx"
my_cat.name = "Bilbo"
my_cat.speak #=> I'm Bilbo and I am a sphynx cat
パラメータは記号であることに注意してください。これはメソッドを作成することで機能します。
class Cat
attr_accessor :breed
end
基本的に同じです:
class Cat
def breed
@breed
end
def breed= value
@breed = value
end
end
アクセスレベル
Rubyには3つのアクセスレベルがあります。彼らはpublic
、 private
、 protected
ます。
private
またはprotected
キーワードに続くメソッドは、そのように定義されます。これらの前に来るメソッドは、暗黙のうちにpublic
メソッドです。
パブリックメソッド
パブリックメソッドは、作成されるオブジェクトの動作を記述する必要があります。これらのメソッドは、作成されたオブジェクトのスコープ外から呼び出すことができます。
class Cat
def initialize(name)
@name = name
end
def speak
puts "I'm #{@name} and I'm 2 years old"
end
...
end
new_cat = Cat.new("garfield")
#=> <Cat:0x2321868 @name="garfield">
new_cat.speak
#=> I'm garfield and I'm 2 years old
これらのメソッドは公開ルビーメソッドであり、新しい猫を初期化する動作とspeakメソッドの動作を記述します。
public
キーワードは不要ですが、 private
またはprotected
エスケープに使用できます
def MyClass
def first_public_method
end
private
def private_method
end
public
def second_public_method
end
end
プライベートメソッド
プライベートメソッドはオブジェクトの外部からアクセスできません。それらはオブジェクトによって内部的に使用されます。 catサンプルを再び使用すると:
class Cat
def initialize(name)
@name = name
end
def speak
age = calculate_cat_age # here we call the private method
puts "I'm #{@name} and I'm #{age} years old"
end
private
def calculate_cat_age
2 * 3 - 4
end
end
my_cat = Cat.new("Bilbo")
my_cat.speak #=> I'm Bilbo and I'm 2 years old
my_cat.calculate_cat_age #=> NoMethodError: private method `calculate_cat_age' called for #<Cat:0x2321868 @name="Bilbo">
上の例でわかるように、新しく作成されたCatオブジェクトは内部的にcalculate_cat_age
メソッドにアクセスできます。 catの名前と年齢をコンソールに出力するprivate calculate_cat_age
メソッドを実行した結果に変数age
を代入します。
my_cat
オブジェクトの外側からcalculate_cat_age
メソッドを呼び出そうとすると、プライベートであるためNoMethodError
れます。それを得る?
プロテクトメソッド
保護されたメソッドは、プライベートメソッドと非常によく似ています。プライベートメソッドと同じ方法でオブジェクトのインスタンスの外部にアクセスすることはできません。ただし、 self
rubyメソッドを使用すると、保護されたメソッドは同じ型のオブジェクトのコンテキスト内で呼び出すことができます。
class Cat
def initialize(name, age)
@name = name
@age = age
end
def speak
puts "I'm #{@name} and I'm #{@age} years old"
end
# this == method allows us to compare two objects own ages.
# if both Cat's have the same age they will be considered equal.
def ==(other)
self.own_age == other.own_age
end
protected
def own_age
self.age
end
end
cat1 = Cat.new("ricky", 2)
=> #<Cat:0x007fe2b8aa4a18 @name="ricky", @age=2>
cat2 = Cat.new("lucy", 4)
=> #<Cat:0x008gfb7aa6v67 @name="lucy", @age=4>
cat3 = Cat.new("felix", 2)
=> #<Cat:0x009frbaa8V76 @name="felix", @age=2>
年齢パラメータをcatクラスに追加し、名前と年齢の3つの新しいcatオブジェクトを作成したことがわかります。私たちはown_age
protectedメソッドを呼び出し、catオブジェクトの年齢を比較します。
cat1 == cat2
=> false
cat1 == cat3
=> true
それを見て、cat1の年齢をself.own_age
保護されたメソッドを使って取得し、cat2の年齢とcat2.own_age
内のcat2.own_ageを呼び出して比較することができました。
クラスメソッドの型
クラスには、インスタンス、シングルトン、クラスメソッドの3種類のメソッドがあります。
インスタンスメソッド
これらは、クラスのinstance
から呼び出すことができるメソッドです。
class Thing
def somemethod
puts "something"
end
end
foo = Thing.new # create an instance of the class
foo.somemethod # => something
クラスメソッド
これらは静的メソッドです。つまり、そのクラスのインスタンス化ではなく、クラスに対して呼び出すことができます。
class Thing
def Thing.hello(name)
puts "Hello, #{name}!"
end
end
クラス名の代わりにself
を使用するのと同じです。次のコードは上記のコードと同じです:
class Thing
def self.hello(name)
puts "Hello, #{name}!"
end
end
書いてメソッドを呼び出す
Thing.hello("John Doe") # prints: "Hello, John Doe!"
シングルトンメソッド
これらはクラスの特定のインスタンスでのみ使用できますが、すべてでは使用できません。
# create an empty class
class Thing
end
# two instances of the class
thing1 = Thing.new
thing2 = Thing.new
# create a singleton method
def thing1.makestuff
puts "I belong to thing one"
end
thing1.makestuff # => prints: I belong to thing one
thing2.makestuff # NoMethodError: undefined method `makestuff' for #<Thing>
singleton
とclass
両方のメソッドは、 eigenclass
class
esと呼ばれます。基本的には、作成されたインスタンスに干渉しないように、そのようなメソッドを保持する匿名クラスを作成することです。
これを行う別の方法は、 class <<
コンストラクタclass <<
です。例えば:
# a class method (same as the above example)
class Thing
class << self # the anonymous class
def hello(name)
puts "Hello, #{name}!"
end
end
end
Thing.hello("sarah") # => Hello, sarah!
# singleton method
class Thing
end
thing1 = Thing.new
class << thing1
def makestuff
puts "I belong to thing one"
end
end
thing1.makestuff # => prints: "I belong to thing one"
動的クラスの作成
クラスは、 Class.new
使用して動的に作成できます。
# create a new class dynamically
MyClass = Class.new
# instantiate an object of type MyClass
my_class = MyClass.new
上記の例では、新しいクラスが作成され、定数MyClass
割り当てられます。このクラスは他のクラスと同様にインスタンス化して使用できます。
Class.new
メソッドは、動的に作成されたクラスのスーパークラスになるClass
を受け入れます。
# dynamically create a class that subclasses another
Staffy = Class.new(Dog)
# instantiate an object of type Staffy
lucky = Staffy.new
lucky.is_a?(Staffy) # true
lucky.is_a?(Dog) # true
また、 Class.new
メソッドはブロックを受け入れます。ブロックのコンテキストは新しく作成されたクラスです。これにより、メソッドを定義することができます。
Duck =
Class.new do
def quack
'Quack!!'
end
end
# instantiate an object of type Duck
duck = Duck.new
duck.quack # 'Quack!!'
新規作成、割り当て、初期化
多くの言語では、特別なnew
キーワードを使用してクラスの新しいインスタンスが作成されます。 Rubyでは、 new
はクラスのインスタンスを作成するためにも使用されますが、キーワードではありません。代わりに、それは静的/クラスメソッドであり、他の静的/クラスメソッドと異なるものではありません。定義はおおよそ次のとおりです。
class MyClass
def self.new(*args)
obj = allocate
obj.initialize(*args) # oversimplied; initialize is actually private
obj
end
end
allocate
は、クラスの初期化されていないインスタンスを作成するための真の「魔法」を実行します。
また、 initialize
の戻り値は破棄され、代わりにobjが返されることに注意してください。あなたが帰国を気にせずに自分のinitializeメソッドをコーディングすることができますこれはなぜそれがすぐに明らかになりself
最後に。
すべてのクラスがClass
から取得する「通常の」 new
メソッドは、上記のように動作しますが、好きなように再定義することも、別の方法で動作する代替メソッドを定義することもできます。例えば:
class MyClass
def self.extraNew(*args)
obj = allocate
obj.pre_initialize(:foo)
obj.initialize(*args)
obj.post_initialize(:bar)
obj
end
end