Latest web development tutorials

Rubyのオブジェクト指向

Rubyは純粋なオブジェクト指向言語で、Rubyは、すべてがオブジェクトの形です。 文字列、数値、さらには真と偽であるオブジェクト:Rubyでの各値は、オブジェクト、も、最も原始的なものです。 クラス自体はClassクラスインスタンスであるオブジェクトです。 この章では、Rubyのオブジェクト指向に関連するすべての主要な機能を説明するように指示します。

クラスは、ニートのパッケージにデータを整理するデータ表現と方法を組み合わせた指定されたオブジェクトを形成するために使用されます。 クラスのデータとメソッドは、クラスのメンバーと呼ばれます。

Rubyのクラス定義

あなたがクラスを定義するときは、実際にデータ・タイプのための青写真を定義します。 これは実際にどのようなデータを定義していませんが、クラス手段の名前は、すなわち何の定義は、クラスのオブジェクトを構成するものの定義は次のようになりますし、どのようなアクションはオブジェクトに対して実行することができます。

クラス定義は、クラス名が続きキーワードクラスで始まりそして分離された表現は、このような定義を削減して、最終的に終わります たとえば、我々は次のように、Boxクラスを定義するためにclassキーワードを使用します。

class Box
   code
end

慣例により、名前が二つ以上の単語が含まれている場合、大文字で始まる各単語の最初の文字を大文字にするが、ここでは(例:キャメルケース)は、区切り文字である必要があります。

Rubyのオブジェクト定義

クラスは、オブジェクトのための青写真を提供するので、基本的に、オブジェクトは、クラスに基づいて作成されます。 私たちは、クラスのオブジェクトを宣言するために、新しいキーワードを使用します。 次の文は、クラスのボックス2つのオブジェクトを宣言します。

box1 = Box.new
box2 = Box.new

initializeメソッド

初期化する方法は、標準的なRubyのクラスメソッドは、他のオブジェクト指向プログラミング言語のコンストラクタの作品に似たクラスのコンストラクタです。あなたが同時にオブジェクトを作成するために、クラスのいくつかの変数を初期化したいときは、この方法が便利です初期化します。 この方法は、次のように、defキーワードの前に配置する必要があり、この方法を使用して、他のRubyの方法と同様に、一連の引数を取ります。

class Box
   def initialize(w,h)
      @width, @height = w, h
   end
end

インスタンス変数

Propertyクラスのインスタンス変数は、オブジェクトのプロパティとなりますクラスオブジェクトを使用しているとき、彼らは作成することです。 各オブジェクトの個々のプロパティは、他のオブジェクトの間で、割り当てられており、価値観を共有しません。 クラス内でクラスの外これらのプロパティにアクセスするには、@演算子を使用することで、アクセスのアクセサメソッドを呼び出しメソッドを使用するのが一般的です。 ここでは、例として上にインスタンス変数としてクラスボックス@widthと@heightをクラスボックスを定義します

class Box
   def initialize(w,h)
      # 给实例变量赋值
      @width, @height = w, h
   end
end

アクセサ(アクセサ)&セッター(セッター)メソッド

クラスの外部変数を使用するために、我々はアクセサが同等のゲッターである内部アクセス方法でこれらの変数を定義する必要があります 次の例では、アクセサメソッドを示しています。

#!/usr/bin/ruby -w

# 定义类
class Box
   # 构造函数
   def initialize(w,h)
      @width, @height = w, h
   end

   # 访问器方法
   def printWidth
      @width
   end

   def printHeight
      @height
   end
end

# 创建对象
box = Box.new(10, 20)

# 使用访问器方法
x = box.printWidth()
y = box.printHeight()

puts "Width of the box is : #{x}"
puts "Height of the box is : #{y}"

上記のコードが実行されると、次の結果を生成します。

Width of the box is : 10
Height of the box is : 20

変数の値にアクセスするために使用するアクセス方法と同様に、Rubyは以下のように定義され、また、setterメソッドとして知られているクラスAの変数の外部値を設定する方法を提供します:

#!/usr/bin/ruby -w

# 定义类
class Box
   # 构造器方法
   def initialize(w,h)
      @width, @height = w, h
   end

   # 访问器方法
   def getWidth
      @width
   end
   def getHeight
      @height
   end

   # 设置器方法
   def setWidth=(value)
      @width = value
   end
   def setHeight=(value)
      @height = value
   end
end

# 创建对象
box = Box.new(10, 20)

# 使用设置器方法
box.setWidth = 30
box.setHeight = 50

# 使用访问器方法
x = box.getWidth()
y = box.getHeight()

puts "Width of the box is : #{x}"
puts "Height of the box is : #{y}"

上記のコードが実行されると、次の結果を生成します。

Width of the box is : 30
Height of the box is : 50

インスタンスメソッド

定義されたインスタンスメソッドや他のメソッドを定義し、それらはdefキーワードを使用しているが、以下の例に示すように、彼らは、クラスのインスタンスで使用することができます。 それらの機能は、インスタンス変数にアクセスするために限定されるものではなく、それ以上の他のタスクを実行するために必要に応じていません。

#!/usr/bin/ruby -w

# 定义类
class Box
   # 构造方法
   def initialize(w,h)
      @width, @height = w, h
   end
   # 实例方法
   def getArea
      @width * @height
   end
end

# 创建对象
box = Box.new(10, 20)

# 调用实例方法
a = box.getArea()
puts "Area of the box is : #{a}"

上記のコードが実行されると、次の結果を生成します。

Area of the box is : 200

クラス変数のクラスメソッド&

クラス変数は、クラス共有変数のすべてのインスタンスです。換言すれば、クラスインスタンス変数は、すべてのオブジェクトのインスタンスにアクセスすることができます。 接頭辞として文字(@@)@ 2とクラス変数次の例に示すように、クラス変数は、クラス定義で初期化する必要があります。

クラスメソッド デフself.methodname()の定義、区切り文字を終了するには、クラスメソッド。以下の実施例に示すように、クラスメソッドは、コールのクラス名classname.methodname形態で使用することができます。

#!/usr/bin/ruby -w

class Box
   # 初始化类变量
   @@count = 0
   def initialize(w,h)
      # 给实例变量赋值
      @width, @height = w, h

      @@count += 1
   end

   def self.printCount()
      puts "Box count is : #@@count"
   end
end

# 创建两个对象
box1 = Box.new(10, 20)
box2 = Box.new(30, 100)

# 调用类方法来输出盒子计数
Box.printCount()

上記のコードが実行されると、次の結果を生成します。

Box count is : 2

to_sメソッド

任意のクラスでは、オブジェクトの文字列表現を返すように定義to_sインスタンスメソッドを持っています。 ここで、幅と高さボックスオブジェクトを表すによれば、簡単な例です:

#!/usr/bin/ruby -w

class Box
   # 构造器方法
   def initialize(w,h)
      @width, @height = w, h
   end
   # 定义 to_s 方法
   def to_s
      "(w:#@width,h:#@height)"  # 对象的字符串格式
   end
end

# 创建对象
box = Box.new(10, 20)

# 自动调用 to_s 方法
puts "String representation of box is : #{box}"

上記のコードが実行されると、次の結果を生成します。

String representation of box is : (w:10,h:20)

アクセス制御

Rubyは、官民または保護されている保護インスタンスメソッドには3つのレベル、を提供します 任意アクセス制御アプリケーションは、Rubyのインスタンスとクラス変数ではありません。

  • Publicメソッド:公共方法は、任意のオブジェクトを呼び出すことができます。initializeメソッドは常にプライベートで除いてデフォルトでは、方法は、パブリックです。
  • プライベートメソッド:プライベートメソッドは、クラスの外からアクセスまたは表示することはできません。唯一のクラスメソッドは、プライベートメンバにアクセスすることができます。
  • プロテクトメソッド:プロテクトメソッドは、唯一のオブジェクトクラスとそのサブクラス呼び出すことができます。アクセスは、内部クラスおよびそのサブクラスで行うことができます。

ここでは3修飾子の構文を示しています簡単な例を示します。

#!/usr/bin/ruby -w

# 定义类
class Box
   # 构造器方法
   def initialize(w,h)
      @width, @height = w, h
   end

   # 实例方法默认是 public 的
   def getArea
      getWidth() * getHeight
   end

   # 定义 private 的访问器方法
   def getWidth
      @width
   end
   def getHeight
      @height
   end
   # make them private
   private :getWidth, :getHeight

   # 用于输出面积的实例方法
   def printArea
      @area = getWidth() * getHeight
      puts "Big box area is : #@area"
   end
   # 让实例方法是 protected 的
   protected :printArea
end

# 创建对象
box = Box.new(10, 20)

# 调用实例方法
a = box.getArea()
puts "Area of the box is : #{a}"

# 尝试调用 protected 的实例方法
box.printArea()

上記のコードが実行されると、次の結果が得られます。 ここでは、最初のメソッド呼び出しは成功しますが、第二の方法は、問題を持っています。

Area of the box is : 200
test.rb:42: protected method `printArea' called for #
<Box:0xb7f11280 @height=20, @width=10> (NoMethodError)

クラス継承

継承、オブジェクト指向プログラミングは、最も重要な概念の一つです。 継承は、私たちははるかに簡単なアプリケーションを作成し、維持することになり、別のクラスに基づいてクラスを定義することができます。

継承は、残念ながら、Rubyは多重継承をサポートしていない、コードおよび高速実行を再利用するために役立ちますが、Rubyサポートのミックスイン。 ミックスインは、インタフェースの一部だけが継承され、多重継承の特定の実装、多重継承のようなものです。

あなたはクラスを作成すると、プログラマはメンバーの既存のクラスから継承する新しいクラスを指定することができますので、ゼロから新しいデータメンバとメンバ関数を書いてはいけません。 既存のクラスは、新しいクラスを派生クラスまたはサブクラスと呼ばれ、基本クラスまたは親クラスと呼ばれています

Rubyはまた、継承され、サブクラスの概念のサブクラスを提供し、次の例は、この概念を示しています。 クラスの構文を拡張することは非常に簡単です。 ただ、class文缶に<文字の名前と親クラスを追加します。 たとえば、次の例では、クラスBigBox ボックスがサブクラスである定義されています。

#!/usr/bin/ruby -w

# 定义类
class Box
   # 构造器方法
   def initialize(w,h)
      @width, @height = w, h
   end
   # 实例方法
   def getArea
      @width * @height
   end
end

# 定义子类
class BigBox < Box

   # 添加一个新的实例方法
   def printArea
      @area = @width * @height
      puts "Big box area is : #@area"
   end
end

# 创建对象
box = BigBox.new(10, 20)

# 输出面积
box.printArea()

上記のコードが実行されると、次の結果を生成します。

Big box area is : 200

メソッドのオーバーロード

あなたは派生クラスで新しい機能を追加することができ、時にはあなたは動作を変更することがありますが、親クラスのメソッドで定義されています。 その後、次の例に示すように関数は、メソッドをオーバーロードすることができ、同じメソッド名を保つことができます。

#!/usr/bin/ruby -w

# 定义类
class Box
   # 构造器方法
   def initialize(w,h)
      @width, @height = w, h
   end
   # 实例方法
   def getArea
      @width * @height
   end
end

# 定义子类
class BigBox < Box

   # 改变已有的 getArea 方法
   def getArea
      @area = @width * @height
      puts "Big box area is : #@area"
   end
end

# 创建对象
box = BigBox.new(10, 20)

# 使用重载的方法输出面积
box.getArea()

上の例の出力は実行します。

Big box area is : 200

演算子の多重定義

我々は、ボックスの幅と高さに*演算子を使用する単項演算子を使用して掛け、+演算子は、2つのボックスオブジェクトのベクトル加算を行い、使用したい - ボックスの幅と高さは否定しました。 ここでボックスオペレータ定義と数学のクラスのバージョンは次のとおりです。

class Box
  def initialize(w,h) # 初始化 width 和 height
    @width,@height = w, h
  end

  def +(other)         # 定义 + 来执行向量加法
    Box.new(@width + other.width, @height + other.height)
  end

  def -@               # 定义一元运算符 - 来对 width 和 height 求反
    Box.new(-@width, -@height)
  end

  def *(scalar)        # 执行标量乘法
    Box.new(@width*scalar, @height*scalar)
  end
end

冷凍オブジェクト

時には、我々は、オブジェクトが変更されないようにしたいです。 オブジェクトでは、凍結法は、それが効果的に一定にオブジェクトを置くことができ、これを達成することができます。 任意のオブジェクトは、Object.freezeを呼び出すことによって凍結させることができます 冷凍オブジェクトはつまり、あなたがそのインスタンス変数を変更することはできません、変更することはできません。

あなたは、指定されたオブジェクトが凍結されているかどうかを確認するObject.frozen?メソッドを使用することができます。 オブジェクトが凍結されている場合は、この方法は、それ以外の場合はfalseを返し、trueを返します。 次の例は、この概念を示しています。

#!/usr/bin/ruby -w

# 定义类
class Box
   # 构造器方法
   def initialize(w,h)
      @width, @height = w, h
   end

   # 访问器方法
   def getWidth
      @width
   end
   def getHeight
      @height
   end

   # 设置器方法
   def setWidth=(value)
      @width = value
   end
   def setHeight=(value)
      @height = value
   end
end

# 创建对象
box = Box.new(10, 20)

# 让我们冻结该对象
box.freeze
if( box.frozen? )
   puts "Box object is frozen object"
else
   puts "Box object is normal object"
end

# 现在尝试使用设置器方法
box.setWidth = 30
box.setHeight = 50

# 使用访问器方法
x = box.getWidth()
y = box.getHeight()

puts "Width of the box is : #{x}"
puts "Height of the box is : #{y}"

上記のコードが実行されると、次の結果を生成します。

Box object is frozen object
test.rb:20:in `setWidth=': can't modify frozen object (TypeError)
        from test.rb:39

クラス定数

あなたは、一定の使用@または@@を必要としない変数の定義への直接数値または文字列値によって、一定の内部クラスを定義することができます。 慣例により、一定の使用大文字の名前。

定数を定義したら、あなたはその値を変更することはできません同じ変数へのアクセスがあるとして、あなたは直接、クラスの内部定数にアクセスすることができますが、外部の定クラスにアクセスする場合は、クラス名を使用する必要あります::定数以下の実施例に示すように

#!/usr/bin/ruby -w

# 定义类
class Box
   BOX_COMPANY = "TATA Inc"
   BOXWEIGHT = 10
   # 构造器方法
   def initialize(w,h)
      @width, @height = w, h
   end
   # 实例方法
   def getArea
      @width * @height
   end
end

# 创建对象
box = Box.new(10, 20)

# 调用实例方法
a = box.getArea()
puts "Area of the box is : #{a}"
puts Box::BOX_COMPANY
puts "Box weight is: #{Box::BOXWEIGHT}"

上記のコードが実行されると、次の結果を生成します。

Area of the box is : 200
TATA Inc
Box weight is: 10

クラス定数を継承することができ、また、インスタンスメソッドと同じが過負荷になっています。

オブジェクトを作成して割り当てる使用します

次の例のように、オブジェクトを初期化すると、そのオブジェクトが新しいメソッドを使用して作成され、この場合には、あなたが初期化されていないオブジェクトを作成するために割り当てる呼び出すことができますコンストラクタを呼び出すことなく、オブジェクトを作成したい、ケースがあるかもしれません次のように:

#!/usr/bin/ruby -w

# 定义类
class Box
   attr_accessor :width, :height

   # 构造器方法
   def initialize(w,h)
      @width, @height = w, h
   end

   # 实例方法
   def getArea
      @width * @height
   end
end

# 使用 new 创建对象
box1 = Box.new(10, 20)

# 使用 allocate 创建两一个对象
box2 = Box.allocate

# 使用 box1 调用实例方法
a = box1.getArea()
puts "Area of the box is : #{a}"

# 使用 box2 调用实例方法
a = box2.getArea()
puts "Area of the box is : #{a}"

上記のコードが実行されると、次の結果を生成します。

Area of the box is : 200
test.rb:14: warning: instance variable @width not initialized
test.rb:14: warning: instance variable @height not initialized
test.rb:14:in `getArea': undefined method `*' 
   for nil:NilClass (NoMethodError) from test.rb:29

クラス情報

Rubyの自己とJavaは、この似ていますが、異なっています。 Javaメソッドは、インスタンスメソッド内で参照されているので、これは通常、現在のオブジェクトを参照します。 ラインでRubyのコード行、自己異なるコンテキスト(文脈)で非常に異なる意味を持ちます。 それでは、次の例を見てみましょう:

#!/usr/bin/ruby -w

class Box
   # 输出类信息
   puts "Class of self = #{self.class}"
   puts "Name of self = #{self.name}"
end

上記のコードが実行されると、次の結果を生成します。

Class of self = Class
Name of self = Box

これは、現在のオブジェクトが実行するように、クラスは、クラスによって定義することができることを意味するだけでなく、プロセス実行中にメタクラス及び親クラスのメソッド定義が利用可能であることを意味します。