C# .Netunityالبرمجةتَعلُمُ البرمجةِ للمبتدئينَ

#18 الفئات Classes – البرمجة بواسطة #C

رمز فتح مرحلة هذا الدرس في تطبيق طورني : IOR

تَعلُمُ البرمجةِ للمبتدئينَ كلياً بواسطةِ #C –  التعامل مع الفئات Classes

الفئات Classes :

ما هو ال Class وكيف يمكن تعريف خصائص Properties له وكيف يمكن إستنساخ مجسمات منه للتعامل مع مشروعنا، هذا ما ستتعرف عليه في هذا الدرس إن شاء الله

كيف يمكننا تعريف متغيرات تشترك في صفات معينة ، ما هو الكلاس ، و كيف يمكننا استنساخ مجسمات منه ؟

هذا ما سوف نتعرف عليه في هذا الدرس بعد الفاصل ان شاء الله

 

السلام عليكم و رحمة الله و بركاته ، و أهلاً و سهلاً بكم في درس جديد من دروس سلسلة تعلم البرمجة للمبتدئين كلياً بواسطة السي شارب

بسم الله الرحمن الرحيم

درسنا اليوم عن الفئات ، طبعا هناك فكرة أريد إيصالها ، و سنلاحظها في الدروس القادمة

هناك بعد المصطلحات التي إن ترجمتها إلى العربية ، فسيكون هناك مشكلة في فهمها ، و ستفقد المهمة الأساسية لها .

تعريف الـ Class

الفئات هو المصطلح الذي وجدته معمماً في الدروس ، و هو المعرف على موسوعة ويكيبيديا .

فالـ Classes هو بتعريفه هو عبارة عن نوع جديد يحتوي على ميزات غير موجودة في الأنواع التقليدية و العادية

رأينا أنه في الدروس سمعنا كثيراً بمصطلح الـ Class  ، مثل الـ Console Class و استطلعنا أن نستعمل دوال منه مثل Write , Read , Clear

و تعاملنا في الدروس السابقة مع الكلمة new و التي قلنا أننا سنحاول تفصيلها لاحقاً قدر الإمكان .

الـ Class هو أهم شيء موجود في البرمجة كائنية التوجه OOP ، و استخدام الكلاس في هذا النوع من البرمجة يحتاج إلى شروحات كثيرة و طويلة ، لكن في هذا الدرس سنحاول تلخيصها و التعريف بموجز عنها ، كي نتمكن من استخدامها في مشاريعنا ، و ذلك لأنها الأساس في المشاريع الكبيرة .

 

نبدأ بإنشاء مشروع جديد كما تعلمنا سابقاً و لا ننسى التأكد من اختيار Visual سي شارب و اختيار Console App

و من باب التأكيد تكلمنا أن الدالة void Main هي الدالة التي يبدأ بها التطبيق بتنفيذ اسطره البرمجية ، و سنتعلم في المستقبل كيف يمكن تغييرها ، فليس شرطاً أن تكون هي الدالة الأساسية ، فيمكننا استدعاء دالة أخرى .

 

كما تحدثنا سابقاً ، فالكلاس يحيط بنا في كل تطبيق ، فمن أول تطبيق قمنا بكتابته في هذا السلسلة كان الكلاس موجوداً

و لكننا لم نعره انتباهاً لأنه يحتاج معرفة الأساسيات لنتمكن من فهمه .

طبعا فكرة الكلاس أو فكرة أن تقوم بإضافة مميزات أو خصائص معينة للـ Object كالتالي :

 

لنفرض أن لديك معرضاُ للسيارات و طلب منك أن تقوم بعمل إحصاء لسيارات معينة

و لو طلبت منك عمل هذا بمعرفتك البرمجية السابقة ، فستقوم بتعريف 3 متغيرات ( المتغير الأول يشير إلى اسم السيارة ، و المتغير الثاني سيشير إلى موديل السيارة ، و المتغير الثالث سيشير إلى السنة التي صنعت السيارة فيها )

و لاحظو أن هذه الثلاث متغيرات ستكون خاصة بالسيارة الأولى ، و بالطبع في المعرض لا يوجد سيارة واحدة .

فإن أردت أن أقوم بإضافة سيارة أخرى ، فما الذي سأقوم بإضافته ؟؟
كالمرة السابقة ، سأقوم بإضافة 3 متغيرات جديدة بنفس وظائف المتغيرات السابقة للسيارة الأولى .

و ذات الشيء لإضافة سيارة ثالثة .

لاحظوا أنني أقوم بإضافة متغيرات كثيرة ، ففي كل مرة أقوم بإضافة 3 متغيرات جديدة ، و أنا كمبرمج أحفظهم فقد قلت له car1 فهي السيارة الأولى ، ثم الشيء الموجود بعد الرقم 1 هو تابع للسيارة الواحدة .

حسناً .. نفترض أنني قمت بعملي هذا و وضعت القيم و تم الأمر بشكل صحيح

و لكن لنفترض أنني قمت بإدخال 50 سيارة على سبيل المثال ، و بعد ذلك وجدت أنه يلزمني إضافة نوع جديد ، أو خاصية جديدة لم اكن منتبهاً لها في البداية ، كإضافة اللون مثلاً فسأقوم بتعريف متغير نصي ، و إن أردت أن أقوم بعمل الخاصية لكل السيارات فسأضطر إلى تكراراها عدة مرات . و لكن هذه الطريقة تقليدية و قاتلة و مضيعة للوقت ، فهي طريقة غير عملية .

لذلك جاء مفهوم الـ Classes ، ألا و هو كيفية بناء فئة معينة تحتوي على خصائص مشتركة ، و يمكن عمل نسخ كثيرة منها ، و يمكن أن نعطي مثالاً للتوضيح ، فلنفترض أن الكلاس عبارة عن قطاعة كعك ، و قطاعة الكعك هي قطعة من الألمنيوم ، فتضعها على الكعك فيخرج معك أشكال مشابهة لشكل القطاعة ، هذه القطاعة لا تستطيع أن تأكلها ، لكن أنت تريد القع التي قمت بقطعها باستخدام هذه الأداة ،

إذا لنقوم بكتابة الكلاس سنقوم بحذف الأسطر السابقة و نبدأ بكتابة الكلاس الخاص بنا ، و نلاحظ أن الكلاس يكتب خارج الكلاس السابق ، فلا يمكن كتابة الكلاس داخل كلاس اخر !

 

الآن أريد تعريف كلاس جديد في منطقة موازية للكلاس الرئيسي ، و هو في داخل الـ namespace الذي قمت بتعريفه منذ البداية .

سأقوم بكتابة الكلاس و يمكنكم الحاق بي …

هنا سأعطيكم ميزة موجودة في برنامج Visual Studio  و هي ميزة جيدة جداً .لاحظوا أنني قمت بكتابة property و هي الخاصية الرئيسية الموجودة في هذا الكلاس ، يمكنني أن أقوم بعملية نسخها لكن من باب التسريع يمكن استخدام الـ Quick Action التي تحدثا عنها سابقاً ، فتكتب prop اختصاراً لـ property ثم تضغط زر Tab مرتين ، فتجد أنه قام مباشرة بعملية إضافة الشكل الكامل للكلاس . و قد تعرفنا عليها سابقاً في درس الـ For Loop حيث قمنا بكتابة for و مباشرة نضغط على Tab مرتين ليقوم بإضافة الشكل الكامل.

إذا نلاحظ هنا أنه من خلال الزل Tab  يمكنني أن أنتقل بين الأماكن الصفراء التي تحتاجها ، و طبعاً int ليس شرطاً أن يكون int فمثلا الخاصية الثانية في السيارة هي من النوع string و ليس int  ، فلذلك سأستبدل الـ int  بـ string ، و أقوم مباشرة بالضغط على Tab للانتقال إلى myProperty  لأقوم بتعديلها إلى Model  . و عند الانتهاء أقوم بعمل Enter  مرتين . إذاً من أجل السرعة بإمكانكم استعمال هذه الميزة ، و بالطبع في البداية ستأخذ وقتاً حتى تعتادوا عليها ، لكن لاحقاً ستكون شيئاً أساسياً .

 

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

الآن إذا أردت استخدام هذا النوع ، و هذا النوع يشبه قطاعة الكعك التي تحدثنا عنها قبل قليل ، فأنا لن أذهب إلى القطاعة و آكلها ! و بهذا لا يمكنني استخدام النوع في تطبيقي مباشرة ، فأنا أحتاج إلى المجسم أو الشيء الذي ينتج من استخدام هذه الأداة ،

لذلك نعود للدالة الرئيسية void Main و سنقوم الآن بعملية استنساخ أو بناء مجسم جديد من النوع car كالتالي :

لاحظوا أنني سأقوم بكتابة Car بحرف كبير و أضع هنا متغير جديد ، و بهذا السطر قمت بتعريف متغير جديد من النوع Car و اسمه myCar و تحدثنا سابقاً عن تعريف المتغيرات ، فكنا نقوم بتعريف متغيرات من النوع int  أو  string  …

أما الآن أصبحنا قادرين على إنتاج أنواع فئات خاصة بنا ، تحتوي على ميزات و خصائص نحن نقوم بكتابتها

إذا بعد أن قمت بتعريف متغير ، و لكي أقوم بإنشائه و التي هي عملية Initialization لاحظوا أنني قمت باستخدام كلمة new ، فنحن نقوم بعملية إنشاء أو استنساخ هذا المجسم من شيء كبير ، ألا و هو الكلاس .

إذاً ..قمت بعملية تعريف و عملية Initialization مباشرة .

لكي أقوم باستخدام هذا المجسم الجديد ، لاحظوا أنني أستطيع الدخول إلى كل الخصائص التي كتبتها هنا من الـ Member Access أو من خاصية الـ IntelliSense ، فإن قمت الآن بكتابة اسم المتغير ثم أضفت نقطة ، فسأحصل على الخصائص التي قمت أنا بكتابتها ، الشركة المصنعة و الموديل و اللون و السنة . هذه الخصائص عليها icon مثل المفتاح ، لتشير إلى أن هذه الخاصية قمت أنا بإضافتها

إذا سأقوم بإدراج قيم إليها ، فقد قمت بتعريف متغير ، و أريد أن اعطيه قيمة للخصائص الموجودة ،

لذلك سأقوم بوضع الشركة المصنعة BMW على سبيل المثال و الموديل و السنة و اللون .

لاحظوا في الجمل الأربع السابقة قمت بإعطاء قيم للخصائص التي قمت بكتابتها .

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

هنا يوجد قضية أود التنويه لها ، إذا قمت بكتابة Car و ضغطت النقطة فإنني لن استطيع التعامل مع الخصائص التي قمت بكتابتها في الأسفل ، أستطيع التعامل معها فقط إذا كانت تابعة لمجسم قمت باستنساخه من الأصل ، و هناك أمور أخرى معينة سنتعرف عليها لاحقاً بإمكاني التعامل معها مباشرة ، لكن في هذا الوضع لا استطيع القيام بطباعة قيمة لمتغير في هذه المنطقة باستخدام اسم الكلاس ، بل أقوم باستدعاء اسم الـ Object الذي تم استنساخه من الكلاس .

إذا في هذه الأسطر الأربع تكلمنا أنه قمنا بعملية وضع قيم ، الآن كيف يمكنني قراءة هذه القيم ،

الأمر بديهي و تكلمنا عنه سابقاً .

إذا قمت بتنفيذ التطبيق فسيقوم بطباعة اسم الشركة المصنعة و موديل السيارة و السنة و اللون

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

إذا هنا قمت بتعريف الكلاس و إضافة خصائص و إسنادها في البرنامج

الآن بإمكانك طالما أنك أنشأت نوع جديد ، و كما تكلمنا سابقاً إذا كان لديك Method فبإمكانك أن ترسل لها parameter لاستخدامه داخل الدالة ، ففي الدروس السابقة أرسنا قيمة int  و بناء عليها حددنا ما الذي يريد المستخدم ،

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

لاحظوا الآن سنتعامل مع نوع جديد من أنواع البيانات ، و هو decimal ، و هو نوع يشبه الـ float إلا أنه يحتوي على خانات أكبر ، و هو أدق ، و يستخدم عادة في التعاملات المالية ، لأنه يحتوي خانات أكثر من float ، فحجم الـ float  في الذاكرة 32 بت ، أما الـ decimal فحجمه تقريباً 128 بت .

لاحظوا هذه الدالة تقوم بعملية ارجاع قيمة decimal  ، لكن هنا أريد أن أقوم بعملية إعطاء أو ادخال متغير من النوع Car و نسميه أي اسم ، و هذا المتغير سأقوم باستخدامه داخل الدالة ، فإنا هنا لا أقول له myCar بل أقول له سأعطيك متغيراً من النوع Car  ، و نسميه أي شيء ؛ هنا سأسميه car بحرف صغير .

إذاً هنا قمت بتعريف متغير جديد ، و سأقوم باستخدامه في داخل الدالة ، إذا سوف أذهب و أقول له كالتالي :

نفترض أنني مبدئياً سأقوم بتعريف متغير من النوع decimal باسم carValue و أسند إليه قيمة مثلاً 1000 دولار ، لاحظوا هنا كما تعرفنا سابقاً عندما يكون لديك فاصلة ، فيجب إضافة الحرف m لتمييزه ، عن النوع float  .

إذا قمت بتعريف متغير و بماشرة سأقوم بإرجاع القيمة .

إذا هذه الـ Method تقوم بأخذ نوع Car و بناء عليه نقوم بإرجاع قيمة معينة ، و لاحظوا إن قمت بعملية طباعة الدالة MarketValue و قمت بإسناد الـ myCar الذي قمت بتعريفه قبل قليل ، و قمت بتشغيل البرنامج ، فإنه سيقوم بإرجاع القيمة الافتراضية . أنا هنا لم أحدد أبداً ، أنا فقط أرسلت المتغير ، و لم أقم باستخدام أي Property خاصة به ، فبما أنني قادر على ارسال نوع الـ Car إلى هذه الـ Method  ، فأنا سأقوم بإضافة قيمة معينة .

نكتب جملة شرطية ، إذا كانت car.Year أقل من 1980 فسعرها سيكون مثلاً 200.5  و لا ننسى الحرف m

ثم نتابع بكتابة الجملة else فالسيارة سعرها 2000.50 مثلاً ، و أيضاً لا ننسى الحرف m .

نقوم بتشغيل البرنامج ، لاحظوا أنه قام بأخذ الـ object الذي قمت تعريفه ، و تعامل مع الـ year  التي قمت بإسنادها أيضاً ، مباشرة قام بتحديد القيمة الراجعة من الـ Property التي تم تعريفها في الكلاس في الكلاس و بناء عليه قام بتحديدها .

الشيء الذي أريد توضيحه هنا في هذه الدالة ، أنه ليس فقط بإمكانك أن تقوم بكتابة الـ Property في الكلاس ، يمكنك أيضاً كتابة Method كاملة تقوم بإرجاع قيم ، فهنا يمكنني أن أقول له كالتالي :

في داخل هذا الكلاس لا اعرف ما هي القيم ، أنا أقوم فقط بأخذ الـ  Propertyو لا أعرف ما هي قيمة الـ object التي أتت لاحقاً و أخذت قيماً متغيرة ، لذلك أقول له في الفئة الخاصة بي إذا كانت السنة للسيارة أقل من قيمة ما ، فقم بإرجاع هذا المتغير ، و لاحظوا أنني قمت بوضعها public ،  و سنتكلم لاحقاً عن الفرق بين public  و private .

إذا سأعود هنا و سأقوم بعمل Comment  لهذا السطر و أقول له كالتالي :

أريد أن تطبع myCar.MarketValue و هذه دالة ترجع قيمة decimal .

في السطر السابق قمت باستدعاء Method داخل الكلاس الرئيسي (program) ، و لكن هنا في الأسفل في السطر الثاني قمت بتعريف Method خاصة داخلياً داخل الكلاس ، و إذا قمت بتطبيق البرنامج فنلاحظ أنه يعطي نفس القيمة التي توقعناها .

 

إذا الكلاس بشكل موجز عبارة عن فئة جديدة نحن  نقوم بتعريفها ، و من ثم بعد انتاجها ، نحن نقوم باستنساخ مجسمات أو Object  منها و وضعها في الذاكرة ،  و أريد أن أوضح أن الكلاس له مكان معين في الذاكرة ، لكن عندما أقوم بإنشاء مجسم أو Object جديد فإنه يقوم بوضعهم في أماكن مختلفة في الذاكرة ، و كأن هذا الـ Car هو int  أو string ، إذا أنا أقوم بعملية بناء مجسمات من هذا الكلاس و أقوم بإعطائها قيماً و التعامل معها .

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

مصطلحات الدرس :

Properties / Property  :

Class :

OOP :

Object :

namespace :

Quick Action :

Initialization :

IntelliSense :

parameter :

float :

decimal :

public :

private :

program :

 

 

الأسطر البرمجية :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SimpleClasses
{
    class Program
    {
        static void Main(string[] args)
        {
            Car myCar = new Car();
            myCar.Make = "BMW";
            myCar.Model = "Sedan";
            myCar.Year = 2017;
            myCar.Color = "Black";

            Console.WriteLine("{0} {1} {2} {3}", 
                myCar.Make, 
                myCar.Model, 
                myCar.Year, 
                myCar.Color);

            //Console.WriteLine(MarketValue(myCar));
            Console.WriteLine(myCar.MarketValue());

            Console.ReadLine();
        }

        private static decimal MarketValue(Car car)
        {
            decimal carValue = 1000.0m;
            if (car.Year < 1980)
                carValue = 200.5m;
            else
                carValue = 2000.50m;

            return carValue;
        }

    }
    class Car
    {
        public string Make { get; set; }
        public string Model { get; set; }
        public int Year { get; set; }
        public string Color { get; set; }

        public decimal MarketValue()
        {
            decimal carValue = 1000.0m;
            if (Year < 1980)
                carValue = 200.5m;
            else
                carValue = 2000.50m;

            return carValue;
        }
    }
}

مقالات ذات صلة

‫3 تعليقات

  1. السلام عليكم و رحمة الله لو سمحت اريد درس oop بواسطة widows froms application و ليس console و شكرا

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *

زر الذهاب إلى الأعلى