Rubyのオブジェクト指向2024 年の最新の入門チュートリアル。このコースでは Rubyのクラス定義,Rubyのオブジェクト定義,initializeメソッド,インスタンス変数,アクセサ(アクセサ)&セッター(セッター)メソッド,インスタンスメソッド,クラス変数のクラスメソッド&,to_sメソッド,アクセス制御,クラス継承,メソッドのオーバーロード,演算子の多重定義,冷凍オブジェクト,クラス定数,オブジェクトを作成して割り当てる使用します,クラス情報, について学習できます。
Rubyは純粋なオブジェクト指向言語で、Rubyは、すべてがオブジェクトの形です。 文字列、数値、さらには真と偽であるオブジェクト:Rubyでの各値は、オブジェクト、も、最も原始的なものです。 クラス自体はClassクラスのインスタンスであるオブジェクトです。 この章では、Rubyのオブジェクト指向に関連するすべての主要な機能を説明するように指示します。
クラスは、ニートのパッケージにデータを整理するデータ表現と方法を組み合わせた指定されたオブジェクトを形成するために使用されます。 クラスのデータとメソッドは、クラスのメンバーと呼ばれます。
あなたがクラスを定義するときは、実際にデータ・タイプのための青写真を定義します。 これは実際にどのようなデータを定義していませんが、クラス手段の名前は、すなわち何の定義は、クラスのオブジェクトを構成するものの定義は次のようになりますし、どのようなアクションはオブジェクトに対して実行することができます。
クラス定義は、クラス名が続き、キーワードクラスで始まり、そして分離された表現は、このような定義を削減して、最終的に終わります。 たとえば、我々は次のように、Boxクラスを定義するためにclassキーワードを使用します。
class Box code end
慣例により、名前が二つ以上の単語が含まれている場合、大文字で始まる各単語の最初の文字を大文字にするが、ここでは(例:キャメルケース)は、区切り文字である必要があります。
クラスは、オブジェクトのための青写真を提供するので、基本的に、オブジェクトは、クラスに基づいて作成されます。 私たちは、クラスのオブジェクトを宣言するために、新しいキーワードを使用します。 次の文は、クラスのボックス2つのオブジェクトを宣言します。
box1 = Box.new box2 = Box.new
初期化する方法は、標準的な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インスタンスメソッドを持っています。 ここで、幅と高さボックスオブジェクトを表すによれば、簡単な例です:
#!/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のインスタンスとクラス変数ではありません。
ここでは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
これは、現在のオブジェクトが実行するように、クラスは、クラスによって定義することができることを意味するだけでなく、プロセス実行中にメタクラス及び親クラスのメソッド定義が利用可能であることを意味します。