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