کلاس
کلاس در حکم یک نقشه برای یک شیء میباشد. شی یک چیز واقعی است که از ساختار، خواص و یا رفتارهای کلاس پیروی میکند. کلاس شامل فیلدها و خواص (properties) و متدها است. وقتی یک شیء میسازید یعنی اینکه یک نمونه از کلاس ساختهاید (در درس ممکن است از کلمات شیء و نمونه به جای هم استفاده شود). در زیر نحوه تعریف کلاس در Ruby نشان داده شده است:
class ClassName field1 field2 ... fieldN method1 method2 ... methodN end
کلمه کلیدی class را قبل از نامی که برای کلاسمان انتخاب میکنیم، مینویسیم. نام کلاس باید با حرف بزرگ شروع شود. در بدنه کلاس فیلدها و متدهای آن قرار داده میشوند. فیلدها، همان متغیرهای نمونه یا Instance Variable ها هستند که نام آنها با علامت @ شروع شده و برای تعریف رفتارها و خاصیت های کلاس، از آنها استفاده می شود. متدها کارهایی هستند که یک کلاس میتواند انجام دهد. در زیر نحوه تعریف و استفاده از یک کلاس ساده به نام Person نشان داده شده است.
1: class Person 2: 3: def initialize(n, a, h) 4: @name = n 5: @age = a 6: @height = h 7: end 8: 9: def tellInformation 10: puts "Name : #{@name}" 11: puts "Age : #{@age} years old" 12: puts "Height: #{@height}cm" 13: end 14: 15: end 16: 17: firstPerson = Person.new("Jack", 21, 160) 18: firstPerson.tellInformation 19: 20: puts #Separator 21: 22: secondPerson = Person.new("Mike", 23, 158) 23: secondPerson.tellInformation
Name : Jack Age : 21 years old Height: 160cm Name : Mike Age : 23 years old Height: 158cm
در کد بالا، ما یک نقشه کلی به نام شخص (Person) ایجاد کرده ایم و گفته ایم که یک شخص می تواند دارای نام (name)، سن (age) و height (قد) باشد. همچنین این شخص می تواند اطلاعاتی در مورد خود، در اختیار ما بگذارد (خطوط 13-9). برای این منظور، یک کلاس به نام Person تعریف کرده ایم (خطوط 15-1). این کلاس دارای دو متد initialize (خطوط 7-3) و tellInformation (خطوط 13-9) و همچنین سه متغیر نمونه (خطوط 6-4) می باشد. متد initialize که به آن متد سازنده هم گفته می شود یک متد از قبل تعریف شده در Ruby است که به شما اجازه میدهد که مقادیری را به هر یک از متغیرهای نمونه اختصاص دهید.
همانطور که گفته شد، در داخل بدنه کلاس متغیرهای نمونه آن تعریف شدهاند (خطوط 6-4). این سه متغیر تعریف شده، خصوصیات واقعی یک فرد در دنیای واقعی را در خود ذخیره میکنند. یک فرد در دنیای واقعی دارای نام، سن، و قد میباشد. در خطوط 13-9 یک متد هم در داخل کلاس به نام ()tellInformation تعریف شده است که رفتار کلاسمان است و مثلاً اگر از فرد سوالی بپرسیم در مورد خودش چیزهایی میگوید. در داخل متد کدهایی برای نشان دادن مقادیر موجود در متغیرها نوشته شده است. نکتهای درباره متغیرها وجود دارد و این است که چون متغیرها در داخل کلاس تعریف و به عنوان اعضای کلاس در نظر گرفته شدهاند، محدوده آنها یک کلاس است.
این بدین معناست که متغیرها فقط میتوانند در داخل کلاس یعنی جایی که به آن تعلق دارند و یا به وسیله نمونه ایجاد شده از کلاس مورد استفاده قرار بگیرند. در خطوط 17 و 22 دو نمونه یا دو شیء از کلاس Person ایجاد میکنیم. همانطور که در این خطوط مشاهده می کنید برای ایجاد یک نمونه از یک کلاس، ابتدا یک نام برای شیء انتخاب کرده، علامت مساوی و بعد از آن نام کلاس را می نویسیم:
firstPerson = Person.new
اگر متد سازنده دارای پارامتر باشد، باید بعد از کلمه new پرانتز گذاشته و به تعداد پارامترهای این متد، آرگومان بنویسیم:
firstPerson = Person.new("Jack", 21, 160)
به این نکته توجه کنید که
در خطوط 17 یک شیء از کلاس Person به نام firstPerson ایجاد کرده ایم و مقادیری به متغیرهای آن اختصاص داده ایم. این مقادیر به سه پارامتر متد سازنده در خط 3 ارسال شده و در خطوط 6-4 به متغیرهای کلاس اختصاص داده می شوند. برای دسترسی به متدهای یک شیء از علامت نقطه (دات) استفاده میشود. به عنوان مثال کد firstPerson.tellInformation نشان دهنده متد tellInformation از شیء firstPerson میباشد. برای چاپ مقادیر متغیرها باید متد tellInformation از شیء firstPerson را فراخوانی میکنیم. در خط 22 نیز مقادیری به شی دومی که قبلاً از کلاس ایجاد شده تخصیص میدهیم و سپس متد tellInformation را فراخوانی میکنیم. به این نکته توجه کنید که firstPerson و secondPerson نسخههای متفاوتی از هر فیلد دارند بنابراین تعیین یک نام برای secondPerson هیچ تاثیری بر نام firstPerson ندارد. اگر بخواهیم درس بالا را به طور خلاصه بیان کنیم، باید بگوییم که:
نکته ای که بهتر است در همین جا به آن اشاره کنیم این است که درحالت عادی نمی توان به متغیرهای یک نمونه همانند متدهای کلاس با استفاده از علامت نقطه دسترسی پیدا کنیم. مثلا اگر بخواهیم به صورت زیر مقدار متغیر نمونه name@ را چاپ کنیم با خطا مواجه می شویم:
puts firstPerson.@name
برای دسترسی به متغیرهای نمونه در یک کلاس باید به ازای هر متغیر یک متد تعریف کرد و با استفاده از این متد به مقدار آن متغیر دست یافت و یا مقداری به آن اختصاص داد. به مثال زیر توجه کنید:
1: class MyClass 2: 3: def setMessage(string) 4: @message = string 5: end 6: 7: def getMessage 8: @message 9: end 10: 11: end 12: 13: x = MyClass.new 14: 15: x.setMessage("Hello World!") 16: 17: puts x.getMessage
Hello World!
در کد بالا ما یک متغیر نمونه به نام message@ تعریف کرده ایم. به این نکته توجه کنید که لازم نیست متغیر نمونه را ابتدا و قبل از متدها تعریف و سپس در داخل متدها از آن استفاده کنید. نوشتن یک متغیر نمونه در داخل یک متد به معنای تعریف و استفاده همزمان از آن است. کار متد اول (5-3) این است که یک مقدار می گیرد و آن را به متغیر نمونه اختصاص می دهد. متد دوم هم مقدار متغیر نمونه را بر می گرداند. در خط 13 یک نمونه از کلاس ایجاد کرده و در خط 15 متد setMessage را صدا می زنیم. در داخل پرانتزهای این متد رشته Hello World را نوشته ایم این رشته در خط 4 به متغیر نمونه message@ اختصاص داده می شود. حال اگر در خط 17 متد getMessage را فراخوانی کنیم، مقدار Hello World که در اصل همان مقدار message@ هست را به ما بر می گرداند.