الأصناف مفهوم محوري في البرمجة كائنية التوجه. في Crystal، كل شيء كائن، ولكل كائن نوع، ويمكنه الاستجابة لبعض الطرق. الأصناف مخططات لإنشاء الكائنات، توفر قيمًا ابتدائية للحالة، مثل المتغيرات، وتنفيذات للسلوك، مثل الطرق. الكائنات هي نسخ من الأصناف تحمل جميع متغيرات المثيل والحالات.
يُعرَّف الصنف باستخدام الكلمة المفتاحية class، متبوعة باسم الصنف مكتوبًا بنمط UpperCamelCase.
class Account
end
لإنشاء نسخة من صنف ما، نادِ اسم الصنف باستخدام الطريقة new.
class Account
end
account = Account.new
في المثال أعلاه، المتغير account هو نسخة من الصنف Account.
عند إنشاء نسخة، تعمل طريقة خاصة تُسمى initialize عمل دالة البناء.
وتُستدعى عند إنشاء النسخة.
تتيح لك دالة البناء ضبط الحالة الابتدائية للنسخة.
يمكن لطريقة initialize أن تستقبل وسائط، تُمرَّر عند إنشاء النسخة.
class Account
def initialize(number)
5 + number # => 9
end
end
Account.new(4)
لا يمكن لطريقة initialize أن تُرجع قيمة يدويًا، بل تُرجع new النسخة المنشأة حديثًا.
class Account
def initialize(number)
5 + number
end
end
Account.new(4)
# => #<Account:0x7f5dc33dcea0>
طريقة المثيل هي طريقة متاحة لنسخة من صنف ما، ويمكن استدعاؤها على تلك النسخة.
تُعرَّف طرق المثيل باستخدام الكلمة المفتاحية def، متبوعة باسم الطريقة.
وتُعرَّف داخل تعريف الصنف.
class Account
def balance
100
end
end
account = Account.new
account.balance # => 100
متغيرات المثيل هي متغيرات متاحة في جميع طرق النسخة.
للوصول إلى متغير مثيل، تحتاج إلى تعريف طريقة مثيل.
يمكن تهيئتها في طريقة initialize.
وتُعرَّف باستخدام البادئة @.
class Account
def initialize
@balance = 100
end
def balance
@balance
end
end
account = Account.new
account.balance
# => 100
يمكن أيضًا تعريف متغيرات المثيل داخل تعريف الصنف.
class Account
@age = 0
end
يمكن تهيئة متغيرات المثيل بوسيط يُمرَّر إلى طريقة initialize.
لأن Crystal لا يستطيع استنتاج نوع الوسيط المستخدم أثناء التهيئة، يجب تحديده.
إذا أردت قراءة المزيد عن هذا، يمكنك الاطلاع على: استنتاج النوع.
لتحديد نوع المتغير، يمكنك استخدام الرمز :، متبوعًا بالنوع.
على سبيل المثال، إذا أردت إنشاء متغير مثيل اسمه balance من النوع Int32، يمكنك فعل ما يلي: @balance : Int32.
أو إذا أردت إنشاء متغير مثيل اسمه raining من النوع Bool، يمكنك فعل ما يلي: @raining : Bool.
هناك عدة أساليب لتنفيذ ذلك، إما بتعريف الوسيط بنوعه في طريقة initialize، ثم إسناد متغير المثيل إلى الوسيط، كما في المثال التالي:
class Account
def initialize(balance : Int32)
@balance = balance
end
def balance
@balance
end
end
account = Account.new(1)
account_2 = Account.new(5)
account.balance
# => 1
account_2.balance
# => 5
أسلوب آخر هو تعريف نوع متغير المثيل في تعريف الصنف بالصيغة: @<variable> : <Type>، كما في المثال التالي:
class Weather
@raining : Bool
def initialize(raining)
@raining = raining
end
def raining
@raining
end
end
weather = Weather.new(true)
weather.raining
# => true
يمكن للطرق تعديل متغيرات المثيل. ويمكن استدعاء هذه الطرق على نسخة الصنف. عندما تعدّل طريقة متغير مثيل، فإن هذا التغيير متاح فقط في نسخة الصنف التي استدعيتها عليها.
class Account
def initialize(balance : Int32)
@balance = balance
end
def withdraw(amount)
@balance -= amount
end
def balance
@balance
end
end
account = Account.new(10)
account_2 = Account.new(10)
account.balance
# => 10
account_2.balance
# => 10
account.withdraw(5)
account.balance
# => 5
account_2.balance
# => 10
طرق الصنف هي طرق تُعرَّف لصنف ما وليس لنسخه.
وهي توفر أسلوبًا لإنشاء طرق لا تعتمد على حالة النسخة.
تُعرَّف باستخدام الكلمة المفتاحية def، متبوعة بـ self.<method name>.
self إشارة إلى النطاق الذي يُستدعى منه self.
في هذه الحالة، يشير إلى الصنف Account.
سيكون الأمر مماثلًا لو كتبت Account.، لكن self. هو الأسلوب المفضل.
class Account
def self.balance
100
end
end
Account.balance
# => 100
صديقك Johannes يحب صناعة العتاد بنفسه (اصنعها بنفسك). لقد بنى للتو آلة لتحضير العصير، وJohannes متحمس لها جدًا. هدف Johannes أن يتمكن من تحضير عصير طازج كل صباح.
آلة تحضير العصير فيها الكثير من الميزات الرائعة. مثل نظام قياس مدمج يخبرك بكمية العصير في الكوب. وفيها أيضًا مؤقت يخبرك بالمدة التي عملت فيها الآلة.
Johannes ليس الأفضل في البرمجة، لكنه يريد كتابة برنامج يتحكم بالآلة. ولذلك طلب منك مساعدته.
في الآلة ضوء Debug، وهو ميكانيزم بسيط: إذا كانت الآلة موصولة بالكهرباء، يكون ضوء Debug مضاءً. ولن يعمل البرنامج إلا إذا كان ضوء Debug مضاءً.
يجب أن تكون هذه الطريقة طريقة صنف باسم JuiceMaker.
عرّف طريقة الصنف JuiceMaker.debug_light_on? التي تُرجع true.
JuiceMaker.debug_light_on?
#=> true
عند تشغيل الآلة، ينبغي أن تُنشئ نسخة من صنف باسم JuiceMaker.
ومن المفترض أن تكون للآلة حالة مُهيَّأة.
ينبغي أن تحمل الحالة المُهيَّأة المعلومات التالية:
false عند تشغيل الآلة.عرّف الحالة المُهيَّأة، التي تأخذ كمية العصير في الكوب كمعامل، وأنشئ الحالة المُهيَّأة.
ينبغي أن تحتوي الحالة المُهيَّأة على متغير نسخة @running مضبوط على false، ومتغير نسخة @fluid مبني على وسيط يُعطى عند تهيئة الصنف.
JuiceMaker.new(5)
#=> #<JuiceMaker:0x10f0b8 @running=false, @fluid=5>
يمكن تشغيل الآلة وإيقافها.
تحتاج إلى تعريف طريقة لتشغيل الآلة.
عند تشغيل الآلة، ينبغي ضبط حالة التشغيل على true.
عرّف الطريقة JuiceMaker#start التي تشغّل الآلة.
juice_maker = JuiceMaker.new(5)
juice_maker.start
juice_maker
#=> #<JuiceMaker:0x10f0b8 @running=true, @fluid=5>
تحتاج الآلة إلى أن تكون قادرة على إخبارك بحالتها.
ينبغي أن تُرجع true إذا كانت الآلة تعمل، وfalse إذا لم تكن تعمل.
عرّف الطريقة JuiceMaker#running? التي تُرجع حالة الآلة.
juice_maker = JuiceMaker.new(5)
juice_maker.start
juice_maker.running?
#=> true
يمكن للآلة أن تضيف عصيرًا إلى الكوب. ويمكن للآلة أن تعرف كمية العصير المُضافة إلى الكوب. تحتاج الآلة إلى مساعدة لمعرفة كمية العصير في الكوب بعد إضافة العصير.
عرّف الطريقة JuiceMaker#add_fluid، التي تأخذ كمية العصير المُضافة كمعامل وتحدّث كمية العصير في الكوب.
juice_maker = JuiceMaker.new(5)
juice_maker.add_fluid(5)
juice_maker
#=> #<JuiceMaker:0x10f0b8 @running=false, @fluid=10>
يمكن تشغيل الآلة وإيقافها.
تحتاج إلى تعريف طريقة لإيقاف الآلة.
لن تُستدعى هذه الطريقة إلا عندما تكون الآلة قيد التشغيل.
عند إيقاف الآلة، ينبغي ضبط حالة التشغيل على false.
وتحتاج الآلة أيضًا إلى مساعدة في تحديد كمية العصير في الكوب بعد إيقافها.
تستهلك الآلة خمس وحدات من العصير في الدقيقة.
عرّف الطريقة JuiceMaker#stop التي تأخذ عدد الدقائق التي عملت فيها الآلة كمعامل وتُرجع كمية العصير في الكوب بعد إيقاف الآلة.
juice_maker = JuiceMaker.new(5)
juice_maker.start
juice_maker
#=> <JuiceMaker:0x10f0b8 @running=true, @fluid=5>
juice_maker.stop(1)
#=> #<JuiceMaker:0x10f0b8 @running=false, @fluid=0>
سجّل في Exercism لتتعلّم وتتقن Crystal عبر 26 مفهومًا142 تمرينًا، وإرشاد بشري حقيقي، وكل ذلك مجانًا.