English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

التفكير بالأحداث Ruby

Ruby هى لغة تعليمى متوجه الأجهزة، كل شيء فى Ruby يظهر بصورة الأجهزة. كل قيمة هى جهاز، حتى الأشياء الأكثر بسيطه: النصوص، الأرقام، حتى الحقيقي والزائف هما أجهزة. الكلاس نفسه هو جهاز أيضًا对象كائن ، هو Class

مثال على فئة

تُستخدم الفئة لتعريف شكل الكائن، وهي تدمج تمثيل البيانات والطرق، وتجمع البيانات والطرق في حزمة منظمة. تُدعى البيانات والطرق في الفئة أعضاء الفئة.

تعريف فئة Ruby

عندما تعرف فئة، فأنت في الواقع تعرف خريطة نوع البيانات. هذا لا يعني إنشاء أي بيانات، بل يعني أن اسم الفئة يعني ماذا، أي أن الكائنات للفئة ستكون مصنوعة من ماذا، وما الذي يمكن تنفيذه على هذه الكائنات. كلمة المفتاحية تعريف الفئة يتم بـclass، يتبعها end اسم الفئة

class Box
   ، وأخيرًا، تبدأ بـ
end

للفصل عن نهاية تعريف الفئة. على سبيل المثال، نستخدم كلمة المفتاحية class لتحديد فئة Box، كما يلي:

الكود

بموجب الإجماع، يجب أن تبدأ الأسماء بأحرف كبيرة، وإذا كانت تحتوي على كلمات متعددة، يجب أن تكون كل كلمة تبدأ بحرف كبير، وليس هناك فاصلة بينها (مثل: CamelCase). لتحديد Ruby كائن كلمة المفتاحية لإنشاء كائنات الفئة. تنص الفئة على خريطة الكائن، لذا فإن الكائنات يتم إنشاؤها بشكل أساسي بناءً على الفئة. نستخدم

box1 = Box.new
box2 = Box.new

طريقة initialize

initialize طريقة هي طريقة فئة Ruby القياسية، وهي مُنشئ الفئة، وهي مشابهة لـ المُنشئ العملية مشابهة. عندما تريد إنشاء كائن مع تهيئة بعض المتغيرات الكلاسيكية في نفس الوقت، يتم استخدام طريقة initialize. تحتوي هذه الطريقة على سلسلة من المعلمات، مثل طرق Ruby الأخرى، يجب وضع def الكلمة المفتاحية، كما يلي:

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

متغيرات المثال

متغيرات المثالهي خصائص الفئة، وتصبح خصائص الكائن عند إنشاء كائن باستخدام الفئة. كل خصائص الكائن تُ赋َّت بشكل منفرد، ولا تشارك القيم مع كائنات أخرى. داخل الفئة، يتم الوصول إلى هذه الخصائص باستخدام عمود الأسهم (@)، وفي الخارج يتم استخدامطرق الوصول (getter)العامللوصول على الطريقة. الآن نستخدم الفئة التي تم تعريفها Box للمثال، لنفترض أن @width و @height متغيرات فئة Box مثال.

class Box
   def initialize(w, h)
      # إعطاء قيمة للمتغير المثال
      @width, @height = w, h
   end
end

طرق الوصول (getter) و طرق التعيين (setter)

للإشارة إلى المتغيرات المحددة في فئة من الخارج، يمكننا تعريف طرق الوصول (getter) للاطلاع عليها. يوضح المثال التالي استخدام طرق الوصول (getter):

在线示例

#!/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 "عرض الصندوق: #{x}"
puts "ارتفاع الصندوق: #{y}"

当上面的代码执行时,它会产生以下结果:

عرض الصندوق: 10
ارتفاع الصندوق: 20

مثل طرق الوصول إلى القيم، يقدم Ruby طريقة لتحويل المعلمات إلى المتغيرات المحددة في الفئة، المعروفة بـطريقة المزود، تعريفها كالتالي:

在线示例

#!/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 "عرض الصندوق: #{x}"
puts "ارتفاع الصندوق: #{y}"

当上面的代码执行时,它会产生以下结果:

عرض الصندوق: 30
ارتفاع الصندوق: 50

بما أن كلا من الطريقتين شائعتين جدًا، قام Ruby بتعريف attr_accessor :variable_name、attr_reader :variable_name、attr_writer :variable_name ثلاث طرق لاستدلال السمات. من بينها:accessor=reader+writer.

بالإضافة إلى ذلك، تأكد من أن يسبق الاسم المتغير :، ويتم فصل الاسم المتغيرات باستخدام ,.

دوال النموذج

دوال النموذجتعريفها مشابهة لتعريف الدوال الأخرى، وهي تستخدم 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 "مساحة الصندوق هي: #{a}"

当上面的代码执行时,它会产生以下结果:

مساحة الصندوق هي: 200

دوال الفئة & متغيرات الفئة

متغير الفئةهي متغيرات مشتركة بين جميع نماذج الفئة. بمعنى آخر، يمكن للنماذج الوصول إلى متغيرات الفئة من جميع النماذج. تبدأ متغيرات الفئة بمقدمة @ @، يجب أن يتم تعريف متغيرات الفئة في تعريف الفئة، كما هو موضح في المثال التالي.

دوال الفئةاستخدام def self.methodname() التعريف، دالة الفئة تنتهي بـ end المفكور 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"
   end
end
 
# إنشاء اثنين من العناصر
box1 = Box.new(10, 20)
box2 = Box.new(30, 100)
 
# استدعاء دالة الطباعة للعدد
Box.printCount()

当上面的代码执行时,它会产生以下结果:

عدد Box: 2

دالة to_s

كل فئة تعريفها تحتوي على to_s مثال على طريقة العودة بناءً على قيم width و height للاعتبار Box:

在线示例

#!/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 为您提供了三个级别的示例方法保护,分别是 public、private 或 protectedRuby 不在示例和类变量上应用任何访问控制。

  • Public 方法: Public 方法可被任意对象调用。默认情况下,方法都是 public 的,除了 initialize 方法总是 private 的。

  • Private 方法: Private 方法不能从类外部访问或查看。只有类方法可以访问私有成员。

  • Protected 方法: Protected 方法只能被类及其子类的对象调用。访问也只能在类及其子类内部进行。

下面是一个简单的示例,演示了这三种修饰符的语法:

在线示例

#!/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 "مساحة صندوق الكبير هي: #@area"
   end
   # 让示例方法是 protected 的
   protected :printArea
end
 
# إيجاد الكائن
box = Box.new(10, 20)
 
# استدعاء طريقة مثال
a = box.getArea()
puts "مساحة الصندوق هي: #{a}"
 
# 尝试调用 protected 的示例方法
box.printArea()

当上面的代码执行时,它会产生以下结果。在这里,第一种方法调用成功,但是第二种方法会产生一个问题。

مساحة الصندوق هي: 200
test.rb:42: protected method `printArea' called for #
<Box:0xb7f11280 @height=20, @width=10> (NoMethodError)

类的继承

继承是面向对象编程中最重要的概念之一。继承允许我们根据另一个类定义一个类,这样使得创建和维护应用程序变得更加容易。

继承有助于重用代码和快速执行,不幸的是,Ruby 不支持多继承,但是 Ruby 支持 mixinsmixin 类似于多继承的一个特定实现,在多继承中,只有接口部分是可继承的。

عند إنشاء فئة، يمكن للبرمجي تحديد أن الفئة الجديدة تورث الأعضاء من فئة موجودة مسبقًا، مما يعني أنه لا يتطلب كتابة أعضاء البيانات الجديدة ومفظة الوظائف من البداية. وتُسمى هذه الفئة الموجودة مسبقًافئة أو فئة آباء، والفئة الجديدة تُسمىفرع أو فرع.

Ruby توفر مفهوم الفرع أيضًا، وهو ما يعني الوراثة. في المثال التالي، سيتم شرح هذا المفهوم. لغة البرمجة Ruby تحتوي على بناء بسيط جدًا للوراثة. كل ما تحتاجه هو إضافة رمز < والاسم المميز للفرع في جملة الفئة. على سبيل المثال، يتم تعريف الفئة التالية: BigBox هو Box فرع:

在线示例

#!/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 "مساحة صندوق الكبير هي: #@area"
   end
end
 
# إيجاد الكائن
box = BigBox.new(10, 20)
 
# عرض المساحة
box.printArea()

当上面的代码执行时,它会产生以下结果:

مساحة صندوق الكبير هي: 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 "مساحة صندوق الكبير هي: #@area"
   end
end
 
# إيجاد الكائن
box = BigBox.new(10, 20)
 
# استخدام الطريقة المحملة لعرض المساحة
box.getArea()

نتيجة التشغيل للعينة أعلاه هي:

مساحة صندوق الكبير هي: 200

تحميل العمليات

نحن نريد استخدام عمودي + لجمع إثنين من كائنات Box، ونريد استخدام عمودي * لتكبير عرض Box وارتفاع Box، ونريد استخدام عمودي - للحصول على عكس عرض Box وارتفاع Box. فيما يلي إصدار Box الكائن مع تعريف عمليات الحساب الرياضية:

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.freeze لجمد الكائن. لا يمكن تعديل الكائن المجمد، أي أنك لا يمكنك تغيير قيمته المثالية.

يمكنك استخدام Object.frozen? يحقق الطريقة إذا كان الكائن المحدد قد تم تجميده. إذا كان الكائن قد تم تجميده، فإن هذه الطريقة ستعود قيمة true، وإلا ستعود قيمة false. يوضح المثال أدناه هذه الفكرة:

在线示例

#!/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 هو كائن مجمد"
else
   puts "كائن Box هو كائن عادي"
end
 
# الآن حاول استخدام طرق التعيين
box.setWidth = 30
box.setHeight = 50
 
# استخدام طرق الوصول
x = box.getWidth()
y = box.getHeight()
 
puts "عرض الصندوق هو: #{x}"
puts "ارتفاع الصندوق هو: #{y}"

当上面的代码执行时,它会产生以下结果:

كائن Box هو كائن مجمد
test.rb:20:في `setWidth=': لا يمكن تعديل كائن مجمد (TypeError)
        من test.rb:39

كميات ثابتة الكائن

يمكنك تعريف كمية ثابتة داخل الكائن، من خلال تخصيص قيمة عددية أو قيمة نصية لمعرف، لا تحتاج تعريف الكمية الثابتة إلى استخدام @ أو @@. وفقًا للعرف، يجب أن تكون أسماء الكميات الثابتة كبيرة الحروف.

بمجرد تعريف الكمية الثابتة، لا يمكنك تغيير قيمتها، يمكنك الوصول إلى الكمية الثابتة داخل الكائن، تمامًا مثل الوصول إلى المتغير، ولكن إذا كنت ترغب في الوصول إلى الكمية الثابتة خارج الكائن، فإنك يجب أن تستخدم classname::constant، كما هو موضح في المثال أدناه.

在线示例

#!/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 "مساحة الصندوق هي: #{a}"
puts Box::BOX_COMPANY
puts "وزن الصندوق هو: #{Box::BOXWEIGHT}"

当上面的代码执行时,它会产生以下结果:

مساحة الصندوق هي: 200
شركة تاتا
وزن الصندوق هو: 10

يمكن تنفيذ الكويات الفئوية والتعديل عليها مثل الطرق المثال.

استخدام allocate لإنشاء كائن

قد يكون هناك حالة تريد فيها إنشاء كائن دون استدعاء بناء الكائن initialize في هذه الحالة يتم إنشاء الكائن، أي باستخدام طريقة new لإنشاء كائن، في هذه الحالة يمكنك استدعاء allocate لإنشاء كائن غير مُعدٍ، كما هو موضح في المثال أدناه:

在线示例

#!/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 "مساحة الصندوق هي: #{a}"
 
# استدعاء طريقة مثال باستخدام box2
a = box2.getArea()
puts "مساحة الصندوق هي: #{a}"

当上面的代码执行时,它会产生以下结果:

مساحة الصندوق هي: 200
test.rb:14: تحذير: لم يتم تحديد المتغير الخاص @width
test.rb:14: تحذير: لم يتم تحديد المتغير الخاص @height
test.rb:14:في `getArea`: لم يتم تعريف الطريقة `*` 
   لأجل nil:NilClass (NoMethodError) من test.rb:29

معلومات الفئة

روبيز سلف و جافايز ثيس مشابهين ولكن مختلفين بشكل كبير. جميع طرق جافا تُستدعى في طريقة مثال، لذا عادة ما يشير ثيس إلى الكائن الحالي. بينما يتم تنفيذ رمز روبي خطوة بخطوة، لذا يمكن أن يكون معنى سلف مختلفًا في سياقات مختلفة. دعونا نرى مثالًا أدناه:.

在线示例

#!/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

这意味着类定义可通过把该类作为当前对象来执行,同时也意味着元类和父类中的该方法在方法定义执行期间是可用的。