مفهوم الـ Class
Class: نكتبها كلاس في العربية. و الكلاس عبارة عن حاوية كبيرة تستطيع أن نحتوي على كل الكود من متغيرات و دوال و كائنات إلخ..
لتعريف كلاس جديد يكفي فقط كتابة الكلمة class
, ثم وضع إسم له, ثم فتح أقواس تحدد بدايته و نهايته. مثال:
class ClassName { }
الآن سنقوم بتعريف كلاس جديد يحتوي على 4 متغيرات, بالإضافة إلى دالة تعرض قيم هذه المتغيرات عندما يتم إستدعاءها.
class Person { String name; String sex; String job; int age; void printInfo() { System.out.println("Name: " +name); System.out.println("Sex: " +sex); System.out.println("Job: " +job); System.out.println("Age: " +age); } }
هنا قمنا بتعريف كلاس إسمه Person
يحتوي على 4 متغيرات بالإضافة إلى دالة تعرض قيم هذه المتغيرات عندما يتم إستدعاءها.
مفهوم الخصائص
أي متغيرات يتم تعريفها بداخل كلاس و خارج أي دالة تسمى خصائص (Attributes), و هذا يعني أن أي كائن من هذا الكلاس سيكون عنده هذه الخصائص.
تستطيع التعامل مع هذه الخصائص من الكائن مباشرةً, بينما المتغيرات العادية لا يمكنك التعامل معها من الكائن.
المتغيرات التي يتم وضعها كباراميترات أو التي يتم تعريفها بداخل الدوال تسمى متغيرات عادية.
ملاحظة
برنامج الـ Netbeans يلون أسماء الخصائص باللون الأخضر, لكي يساعدك في التفريق بين المتغيرات العادية و المتغيرات التي يتم إعتبارها خصائص.
و تذكر أن المتغيرات تسمى خصائص, لأن أي كائن من هذا الكلاس سيملك نسخته الخاصة منها.
مفهوم الـ Object
object: تعني كائن في اللغة العربية. و الكائن عبارة عن نسخة مطابقة لكلاس معين.
بما أن الكائن عبارة عن نسخة من الكلاس, يمكننا القول أنه لا يمكن إنشاء كائن إذا لم يكن هناك كلاس.
إذاً في مفهوم برمجة الكائنات نقوم بإنشاء كلاس معين يسمونه blue print أي (النسخة الخام أو النسخة الأصلية) , و بعدها ننشئ نسخة أو أكثر من هذا الكلاس و نفعل بها ما نريد بدون أن نغير محتويات الكلاس الأساسي و هكذا نكون حافظنا على كودات الكلاس الأساسي لأننا نعدل على النسخ و ليس عليه مباشرةً.
بما أن الكائن عبارة عن نسخة من الكلاس. لتعريف كائن من كلاس معين يجب وضع إسم الكلاس ثم وضع إسم للكائن.
Person ahmad = new Person();
هنا قمنا بتعريف كائن من الكلاس Person
إسمه ahmad
.
إذاً الكائن ahmad
سيكون عنده نسخة خاصة فيه من خصائص الكلاس Person
.
ملاحظة: الكود new Person()
هو الذي يقوم فعلياً بتوليد كائن من الكلاس. و هو يعطي قيم أولية للخصائص الموجودة فيه و ستفهم ذلك لاحقاً.
سنقوم الآن بكتابة نفس الكود السابق على مرحلتين لتحصل على كائن من الكلاس Person
.
Person ahmad;// Person سيمثل كائن من الكلاس ahmad هنا قلنا أن ahmad = new Person();// Person يمثل كائن من الكلاس ahmad هنا أصبح ,ahmad و بعدها قمنا بتخزينه في Person هنا قمنا بتوليد كائن من الكلاس
طريقة التعامل مع الكائنات
نقوم بإنشاء كائن من الكلاس.
بعدها نقوم بإدخال قيم لخصائصه, إستدعاء دواله إلخ..
لاستدعاء أي شيء موجود في الكائن الذي خلقناه
نضع إسم الكائن.
ثم نقطة.
ثم الشيء الذي نريد الوصول إليه ( سواء إسم متغير أو دالة ).
نصائح عليك إتباعها
يفضل إنشاء كل كلاس في ملف جافا خاص.
إبدأ إسم الكلاس دائماً بحرف كبير.
إبدأ إسم الكائن دائماً بحرف صغير.
علاقة الـ Object بالـ Class
الكائنات تساعد المبرمج كثيراً, فمثلاً إذا كنت تنوي إنشاء برنامج بسيط لحفظ معلومات أشخاص, هل ستنشئ كلاس لكل شخص ؟!
طبعاً لا, بل تنشئ كلاس واحد فقط يمثل شخص, و تضع فيه الأشياء الأساسية التي تريدها أن تكون موجودة عند كل شخص. ثم تنشئ منه كائنات قدر ما شئت, و عندها يصبح كل كائن من هذا الكلاس عبارة عن شخص له معلوماته الخاصة.
كما تلاحظ قمنا بإنشاء كلاس يحتوي على المعلومات الأساسية التي نريد تعبئتها لكل شخص.
بعدها قمنا بإنشاء 4 كائنات ( أي 4 أشخاص ), ثم قمنا بإدخال معلومات خاصة لكل كائن فيهم.
الآن في حال قمت بإضافة أي متغير أو دالة جديدة في الكلاس Person
, فإن أي كائن من هذا الكلاس سيملك نسخة من الشيء الجديد الذي أضفته.
و في حال قمت بتعديل كود معين في الكلاس Person
, فأيضاً سيتم تعديل هذا الكود عند جميع الكائنات من هذا الكلاس.
مثال
الآن سنقوم بإنشاء الكلاس Person
و إنشاء كائنات منه في الكلاس الذي يحتوي على الدالة main()
.
إنتبه: يجب إنشاء الكلاس Person
و الكلاس Main
في نفس الـ package حتى يعمل الكود بشكل صحيح. ستفهم السبب في الدرس التالي.
public class Person { //// هنا قمنا بتعريف 4 خصائص String name; String sex; String job; int age; // هنا قمنا بتعريف دالة تطبع محتوى كل خاصية عندما يتم استدعاءها void printInfo() { System.out.println("Name: " +name); System.out.println("Sex: " +sex); System.out.println("Job: " +job); System.out.println("Age: " +age); System.out.println(); } }
Main.java
public class Main { public static void main(String[] args) { // Person هنا قمنا بإنشاء كائنات من الكلاس Person p1 = new Person();// سيمثل محمد p1 الكائن Person p2 = new Person();// سيمثل روز p2 الكائن Person p3 = new Person();// سيمثل أحمد p3 الكائن Person p4 = new Person();// سيمثل ربيع p4 الكائن // p1 هنا قمنا بتحديد خصائص الكائن p1.name = "Mhamad"; p1.sex = "Male"; p1.job = "Programmer"; p1.age = 21; // p2 هنا قمنا بتحديد خصائص الكائن p2.name = "rosa"; p2.sex = "Female"; p2.job = "Secretary"; p2.age = 22; // p3 هنا قمنا بتحديد خصائص الكائن p3.name = "Ahmad"; p3.sex = "Male"; p3.job = "Doctor"; p3.age = 34; // p4 هنا قمنا بتحديد خصائص الكائن p4.name = "Rabih"; p4.sex = "Male"; p4.job = "Engineer"; p4.age = 27; // هنا قمنا بعرض خصائص كل كائن p1.printInfo(); p2.printInfo(); p3.printInfo(); p4.printInfo(); } }
•سنحصل على النتيجة التالية عند التشغيل.
Name: Mhamad Sex: Male Job: Programmer Age: 21 Name: Rose Sex: Female Job: Secretary Age: 22 Name: Ahmad Sex: Male Job: Doctor Age: 34 Name: Rabih Sex: Male Job: Engineer Age: 27
مفهوم الـ Constructor
Constructor: تكتب كونستركتور بالعربية.
من أهم الأشياء التي عليك التفكير بها بعد إنشاء كلاس جديد, هي تسهيل طريقة خلق كائنات من هذا الكلاس.
من هنا جائت فكرة الكونستركتور و الذي هو عبارة عن دالة لها نوع خاص, يتم إستدعائها أثناء إنشاء كائن لتوليد قيم أولية للخصائص الموجودة فيه.
بما أنه لا يمكن إنشاء كائن من كلاس إلا من خلال كونستركتور, سيقوم مترجم جافا بتوليد كونستركتور إفتراضي فارغ عنك إذا وجد أن الكلاس الذي قمت بتعريفه لا يحتوي على أي كونستركتور.
•إذا قمنا بتعريف كلاس إسمه Person
و لم نقم بتعريف كونستركتور له كما في الكلاس التالي.
class Person { }
•سيقوم المترجم بإنشاء كونستركتور فارغ بشكل تلقائي عننا كالتالي.
class Person { public Person() { } }
نقاط مهمة حول الكونستركتور
كل كلاس يتم إنشاءه, يحتوي على كونستركتور واحد على الأقل. و حتى إن لم تقم بتعريف أي كونستركتور, سيقوم المترجم بإنشاء واحد إفتراضي عنك.
في كل مرة يتم إنشاء كائن جديد, يجب استدعاء كونستركتور حتى يتم إنشاء هذا الكائن.
القاعدة الأساسية عند تعريف كونستركتور هي أنه يجب أن يحمل نفس إسم الكلاس و يكون نوعه
public
.في حال قمت بتعريف كونستركتور, لن يقوم المترجم بإنشاء واحد إفتراضي, أي لن يعود هناك كونستركتور إفتراضي.
يمكنك تعريف أكثر من كونستركتور. و يمكنك دائماً إنشاء كونستركتور فارغ, حتى تستخدمه إن كنت لا تريد إعطاء قيم أولية محددة للخصائص عند إنشاء كائن.
الآن سنرجع إلى الكلاس Person
, و سنضيف فيه 2 كونستركتور, واحد فارغ ( أي مثل الإفتراضي ), و آخر يمكننا من خلاله إدخال قيم مباشرةً في الخصائص الموجودة في الكائن بدل إستدعاء كل خاصية موجودة فيه.
package person; public class Person { // هنا قمنا بتعريف 4 خصائص String name; String sex; String job; int age; // إفتراضي constructor فارغ, أي كأننا قمنا بتعريف constructor هنا قمنا بتعريف public Person() { } // ثاني, الهدف منه إعطاء قيم لجميع الخصائص الموجودة في الكائن عند إنشاءه مباشرةً constructor هنا قمنا بتعريف // عليك إدخال 4 قيم من نفس النوع و بالترتيب الموضوع constructor عند استدعاء هذا الـ public Person(String n, String s, String j, int a) { name = n;// name سيتم وضعه كقيمة للخاصية n الذي سيتم تخزينه في String الـ sex = s;// sex سيتم وضعه كقيمة للخاصية s الذي سيتم تخزينه في String الـ job = j;// job سيتم وضعه كقيمة للخاصية j الذي سيتم تخزينه في String الـ age = a;// age سيتم وضعه كقيمة للخاصية a الذي سيتم تخزينه في int الـ } // هنا قمنا بتعريف دالة تطبع محتوى كل خاصية عندما يتم استدعاءها void printInfo() { System.out.println("Name: " +name); System.out.println("Sex: " +sex); System.out.println("Job: " +job); System.out.println("Age: " +age); System.out.println(); } }
Main.java
public class Main { public static void main(String[] args) { // Person هنا قمنا بإنشاء كائنات من الكلاس Person p1 = new Person("Mhamad", "Male", "Programmer", 21);// يمثل الشخص محمد مع تحديد كامل خصائصه p1 الكائن Person p2 = new Person("rosa", "Female", "Secretary", 22);// يمثل الشخص روز مع تحديد كامل خصائصه p2 الكائن Person p3 = new Person("Ahmad", "Male", "Doctor", 34);// يمثل الشخص أحمد مع تحديد كامل خصائصه p3 الكائن Person p4 = new Person("Rabih", "Male", "Engineer", 27);// يمثل الشخص ربيع مع تحديد كامل خصائصه p4 الكائن // الفارغ, فإضطررنا إلى إدخال قيمة لكل خاصية موجودة فيه constructor هنا قمنا بإنشاء كائن جديد باستخدام الـ Person p5 = new Person(); // p5 هنا قمنا بتحديد خصائص الكائن p5.name = "lina"; p5.sex = "Female"; p5.job = "Graphic Designer"; p5.age = 24; // هنا قمنا بعرض خصائص كل كائن p1.printInfo(); p2.printInfo(); p3.printInfo(); p4.printInfo(); p5.printInfo(); } }
•سنحصل على النتيجة التالية عند التشغيل.
Name: Mhamad Sex: Male Job: Programmer Age: 21 Name: Rose Sex: Female Job: Secretary Age: 22 Name: Ahmad Sex: Male Job: Doctor Age: 34 Name: Rabih Sex: Male Job: Engineer Age: 27 Name: Lina Sex: Female Job: Graphic Designer Age: 24
المتغيرات التي يتم وضعها في الكلاس تقسم إلى ثلاث فئات أساسية ذكراناها في الجدول التالي.
بالإنجليزية | معناها |
---|---|
Local Variables | هي المتغيرات التي يتم تعريفها بداخل أي دالة, أو constructor, أو بداخل block ( مثل الحلقات, الجملة switch إلخ.. ). |
Instance Variables | هي المتغيرات التي يتم تعريفها بداخل الكلاس و خارج حدود أي دالة أو constructor, أو block. تسمى أيضاً Global Variables. |
Class Variables | هي المتغيرات التي يتم تعريفها كـ static بداخل الكلاس و خارج حدود أي دالة أو constructor, أو block. |
class VariablesTypes { // block لأنه تم تعريفهم بداخل الكلاس و خارج أي دالة أو Instance Variables تعتبر ( a, b, c, d ) المتغيرات // ستفهم معناها في الدرس التالي, لكننا وضعناها فقط لتفهم الأسماء المستخدمة ( public, protected, private ) الكلمات int a; public int b; protected int c; private int d; // static لأن نوعه Class Variable يعتبر e المتغير static int e; // لأنه تم تعريفها بداخل الدالة Local Variables تعتبر ( x, y, z ) المتغيرات public int sum(int x, int y) { int z = x + y; return z; } }
الكلمة this
الكلمة this
هي كلمة محجوزة في لغة جافا, و هي تستخدم للإشارة إلى الـ Global Variables, و تستخدم أيضاً للإشارة إلى الكائن الحالي. و يمكن استخدامها في أماكن عديدة ستتعرف عليها في دروس مقبلة.
في هذا الدرس سنستخدمها للتفرقة بين المتغيرات التي تم تعريفها بداخل الدوال Local Variables و بين المتغيرات التي تم تعريفها بداخل الكلاس و خارج الدوال Global Variables.
سنرجع إلى الكلاس Person
و سنقوم باستخدام الكلمة this
عدة مرات لمعرفة تأثيرها على الكود.
في هذا المثال لم نغير أي كود كان موجود, لكننا أضفنا كلمة this
في كل مكان كنا نقصد فيه أننا نريد الوصول للخصائص.
public class Person { String name; String sex; String job; int age; public Person() { } // لأن أسماء الباراميترات الموضوعة ليست نفسها أسماء الخصائص this هنا لا يوجد داعي لاستخدام الكلمة public Person(String n, String s, String j, int a) { this.name = n;// الموجودة في الكلاس name الموجود في الدالة, سيتم وضعها في الخاصية n القيمة التي سيتم إدخالها في المتغير this.sex = s;// الموجودة في الكلاس sex الموجود في الدالة, سيتم وضعها في الخاصية s القيمة التي سيتم إدخالها في المتغير this.job = j;// الموجودة في الكلاس job الموجود في الدالة, سيتم وضعها في الخاصية j القيمة التي سيتم إدخالها في المتغير this.age = a;// الموجودة في الكلاس age الموجود في الدالة, سيتم وضعها في الخاصية a القيمة التي سيتم إدخالها في المتغير } // لأن الدالة لا تحتوي على باراميترات و بالتالي سيفهم المترجم أنك تقصد عرض قيم الخصائص الموجودة في الكائن حتى لو لم تستخدمها this هنا لا يوجد داعي لاستخدام الكلمة void printInfo() { System.out.println("Name: " +this.name); System.out.println("Sex: " +this.sex); System.out.println("Job: " +this.job); System.out.println("Age: " +this.age); System.out.println(); } }
•سنحصل على نفس النتيجة السابقة عند التشغيل.
Name: Mhamad Sex: Male Job: Programmer Age: 21 Name: Rose Sex: Female Job: Secretary Age: 22 Name: Ahmad Sex: Male Job: Doctor Age: 34 Name: Rabih Sex: Male Job: Engineer Age: 27 Name: Lina Sex: Female Job: Graphic Designer Age: 24
في هذا المثال سنستخدم الكلمة this
عند الحاجة لها فقط.
•هنا قمنا بوضع أسماء الباراميترات مثل أسماء الخصائص.
إذاً هنا يجب وضع الكلمة this
إذا كنا نريد الوصول للخصائص و إلا ستحدث أخطاء منطقية في البرنامج.
public class Person { String name; String sex; String job; int age; public Person() { } // للتفرقة بين الباراميترات و الخصائص الموجودة في الكائن this هنا يجب إستخدام الكلمة public Person(String name, String sex, String job, int age) { this.name = name;// الموجودة في الكلاس name الموجود في الدالة, سيتم وضعها في الخاصية name القيمة التي سيتم إدخالها في المتغير this.sex = sex;// الموجودة في الكلاس sex الموجود في الدالة, سيتم وضعها في الخاصية sex القيمة التي سيتم إدخالها في المتغير this.job = job;// الموجودة في الكلاس job الموجود في الدالة, سيتم وضعها في الخاصية job القيمة التي سيتم إدخالها في المتغير this.age = age;// الموجودة في الكلاس age الموجود في الدالة, سيتم وضعها في الخاصية age القيمة التي سيتم إدخالها في المتغير } // لأن الدالة لا تحتوي على باراميترات و بالتالي سيفهم المترجم أنك تقصد عرض قيم الخصائص الموجودة في الكائن حتى لو لم تستخدمها this هنا لا يوجد داعي لاستخدام الكلمة void printInfo() { System.out.println("Name: " +name); System.out.println("Sex: " +sex); System.out.println("Job: " +job); System.out.println("Age: " +age); System.out.println(); } }
•سنحصل على نفس النتيجة السابقة عند التشغيل.
Name: Mhamad Sex: Male Job: Programmer Age: 21 Name: Rose Sex: Female Job: Secretary Age: 22 Name: Ahmad Sex: Male Job: Doctor Age: 34 Name: Rabih Sex: Male Job: Engineer Age: 27 Name: Lina Sex: Female Job: Graphic Designer Age: 24
في هذا المثال وضعنا أسماء الباراميترات في الكونستركتور نفس أسماء الخصائص و لم نستخدم الكلمة this
للتفريق بينهم.
إذاً هنا لن تحدث أخطاء تؤدي إلى إيقاف البرنامج بل ستحدث أخطاء منطقية نلاحظها عند تشغيل البرنامج.
•هنا قمنا بوضع أسماء الباراميترات مثل أسماء الخصائص.
سيتسبب هذا الكود بأخطاء منطقية تظهر فقط عند تشغيل البرنامج.
public class Person { String name; String sex; String job; int age; public Person() { } // سيسبب مشكلة لأن المترجم لن يستطيع التفرقة بين الباراميترات و الخصائص الموجودة في الكائن this هنا عدم إستخدام الكلمة // غير مفيد و يحتوي على أخطاء منطقية constructor إذاً هذا الـ public Person(String name, String sex, String job, int age) { name = name;// من جديد name سيتم وضعها في الباراميتر name القيمة التي سيتم إدخالها في المتغير sex = sex;// من جديد sex سيتم وضعها في الباراميتر sex القيمة التي سيتم إدخالها في المتغير job = job;// من جديد job سيتم وضعها في الباراميتر job القيمة التي سيتم إدخالها في المتغير age = age;// من جديد age سيتم وضعها في الباراميتر age القيمة التي سيتم إدخالها في المتغير } // لأن الدالة لا تحتوي على باراميترات و بالتالي سيفهم المترجم أنك تقصد عرض قيم الخصائص الموجودة في الكائن حتى لو لم تستخدمها this هنا لا يوجد داعي لاستخدام الكلمة void printInfo() { System.out.println("Name: " +name); System.out.println("Sex: " +sex); System.out.println("Job: " +job); System.out.println("Age: " +age); System.out.println(); } }
•سنحصل على النتيجة التالية عند التشغيل.
•لاحظ أن الكائنات التي استخدمت الكونستركتور الأول فقط هي التي حدث فيها أخطاء منطقية.
Name: noll Sex: noll Job: noll Age: 0 Name: noll Sex: noll Job: noll Age: 0 Name: noll Sex: noll Job: noll Age: 0 Name: noll Sex: noll Job: noll Age: 0 Name: lina Sex: Female Job: Graphic Designer Age: 24
ليست هناك تعليقات:
إرسال تعليق
ملحوظة: يمكن لأعضاء المدونة فقط إرسال تعليق.