English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Ruby هى لغة تعليمى متوجه الأجهزة، كل شيء فى Ruby يظهر بصورة الأجهزة. كل قيمة هى جهاز، حتى الأشياء الأكثر بسيطه: النصوص، الأرقام، حتى الحقيقي والزائف هما أجهزة. الكلاس نفسه هو جهاز أيضًا对象كائن ، هو Class
مثال على فئة
تعريف فئة Ruby
عندما تعرف فئة، فأنت في الواقع تعرف خريطة نوع البيانات. هذا لا يعني إنشاء أي بيانات، بل يعني أن اسم الفئة يعني ماذا، أي أن الكائنات للفئة ستكون مصنوعة من ماذا، وما الذي يمكن تنفيذه على هذه الكائنات. كلمة المفتاحية تعريف الفئة يتم بـclass، يتبعها end اسم الفئة
class Box ، وأخيرًا، تبدأ بـ end
للفصل عن نهاية تعريف الفئة. على سبيل المثال، نستخدم كلمة المفتاحية class لتحديد فئة Box، كما يلي:
بموجب الإجماع، يجب أن تبدأ الأسماء بأحرف كبيرة، وإذا كانت تحتوي على كلمات متعددة، يجب أن تكون كل كلمة تبدأ بحرف كبير، وليس هناك فاصلة بينها (مثل: CamelCase). لتحديد Ruby كائن كلمة المفتاحية لإنشاء كائنات الفئة. تنص الفئة على خريطة الكائن، لذا فإن الكائنات يتم إنشاؤها بشكل أساسي بناءً على الفئة. نستخدم
box1 = Box.new box2 = Box.new
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) للاطلاع عليها. يوضح المثال التالي استخدام طرق الوصول (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 مثال على طريقة العودة بناءً على قيم 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
يمكن تنفيذ الكويات الفئوية والتعديل عليها مثل الطرق المثال.
قد يكون هناك حالة تريد فيها إنشاء كائن دون استدعاء بناء الكائن 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
这意味着类定义可通过把该类作为当前对象来执行,同时也意味着元类和父类中的该方法在方法定义执行期间是可用的。