نظرة أعمق على Class & Objects في #C

نظرة أشمل وأعمق عن التعامل مع Class وobject في C# تكلم عن طريقة بناء واستخدام عناصر الـ Class بأنواعها..كيفية استخدام الكلمة الأساسية this و readonly

نظرة أعمق على Class & Objects في  C# 

تُعتبر لغة البرمجة سي شارب إحدى اللغات القوية والمستخدمة على نطاق واسع في تطوير التطبيقات المتنوعة. سي شارب تدعم استخدام البرمجة الموجهة للكائنات OOP والتي من بين مفاهيمها الأساسية الـ Class و Object كعناصر جوهرية في البرمجة الكائنية. يهدف هذا المقال إلى تقديم نظرة عميقة على استخدامات هذه المفاهيم في لغة سي شارب…

في مقال مقدمة الى Class & Object تكلمنا عن نهج البرمجة الموجهة للكائنات OOP وشرحنا بإيجاز طريقة العمل مع Class and Object في لغة سي شارب، في هذا المقال نتابع مع نظرة أشمل وأعمق عن التعامل مع Class and object في  C# . ففي هذا المقال نتكلم عن طريقة بناء واستخدام عناصر الـ Class بأنواعها…وكيفية استخدام الكلمة الأساسية this لتعزيز تفاعل الكائنات، بالإضافة إلى توضيح أهمية استخدام الكلمة الأساسية Readonly . لنبدأ..

نظرة على Class و Object

عرفنا في مقال البرمجة الموجهة للكائنات OOP ، أن الركائز الأساسية في نهج البرمجة الموجهة للكائنات هما الفئات Classes و الكائنات Objects ، في مقال مقدمة في Class and Object ، ذكرنا أن الـ class نموذج يحتوي مجموعة من السمات Attributes والوظائف Methods التي تحدد سلوك الكائنات Object التي تنشأ عنها حيث أن الكائن Object هو نسخة الـ Class مع بيانات حقيقية.

تعرفنا في مقال مقدمة فيCalss & Object على طريقة انشاء الـ class بواسطة الكلمة الأساسية class ، علينا ان نذكر ان الـ Class قد يكون عام او خاص (public /private)، كما نه لابد أن يحتوى على عناصر فالـ Class الفارغ لا يمكنه عمل شيء. يحتوي الـ Class على بالإضافة الى المتغيرات Variables والدوال Methods على الخصائص Properties والـ Constructors.

ام عن الـ Object، فيكون الاعلان عنه كتالي :

 ClassName ObjectName = new ClassName();

نرى استخدام الكلمة الأساسية new بعد معامل التعيين (=)، تقوم new  بتهئة مكان للـ Object في الذاكرة، فمثلاً ان اردنا ننشئ object للدائرة من الـ Class الذي اسمه Circle وكتبنا:

 Circle circle1 ;

هذه التعلمية صحيحة لكنها فعلياً لاتشير لأي موقع على الذاكرة لذالك لابد من تهيئة موقع الـ object ، والذي يكون كتالي :

 Circle = new Circle (); 

هنا قام البرنامج بحجز موقع من الذاكرة لهذا الـ object ، مع معامل التعين (=) يمكن ايضاً نقل بيانات Object الى object آخر، لاحظ /ي الشكل التالي:

اتوماتيكياً تتخلص  C#  من كل مواقع الذاكرة التي لايشير اليها بواسطة الــ Object.



عناصر الـ Class الثابتة (Static) وغير الثابتة (Non-static)

أشرنا إلى ان الـ Class لابد ان يحتوى على عناصر من هذه العناصر الدوال Method و المتغيرات Variables والتي قد تكون عناصر ثابتة (ٍStatic Members) أو غير الثابتة (Non-static Members) بالطبع يختلف التعامل مع هذه العناصر بحسب نوعها لنرى:


العناصر غير الثابتة ( Non-static Members):

العناصر غير الثابتة (non-static members) أو مايعرف بـ InstanceMembers وهي المتغيرات Variables والدوال Methods التي لا يشمل بيان الإعلان عنها على كلمة static. وترتبط هذه العناصر بالـ Object، القيم المستخدمة في عناصر البيانات من هذا النوع تكون مختلفة لكل object حيث يحتفظ كل object بنسختة الخاصة ويتم الوصول للعناصر الـ Non-static بواسطة الـ Object المثال التالي يوضح استخدامها:

في Circle Class نضيف متغيرات ودوال من نوع Non-static :


...........
public class Circle {
    //declaring instance variables 
    public int circle_num = 0; 
  	public double redius; //radius of circle
	//constructos
  	public Circle (){
      circle_num++;
    }
    public Circle (double r){
      redius = r;
      circle_num++;
    }
  	//Non-Static Methods for calculate circumference and area 
  	private double Circumference() { return 2 * 3.14 * redius; }
  	private double Area() {	return 3.14 * redius * redius;}
    //A non-static method for printing the output
    public void CircleInfo(){
      Console.WriteLine("Circle number is:{0}\nCircle circumference is :{1}\nCircle area is:{2}", circle_num , Circumference() ,Area());
    }
  }
...........

في الـ Class الخاص بالتنفيذ نقوم بإنشاء اكثرمن Object كتالي:


...........
public static void Main(string[] args)
		{
		  //Create the first object 
		  Circle circle1 = new Circle();
		//Access to non-static members via object 
		  circle1.redius = 5.0;
		  circle1.CircleInfo();
		  //Create the second object 
		  Circle circle2 = new Circle(3.0);
		  circle2.CircleInfo();	
		}
...........

الـ Output للمثال:

Circle number is:1
Circle circumference is :31.4
Circle area is:78.5
Circle number is:1
Circle circumference is :18.84
Circle area is:28.26

المثال متوفر بالكامل متوفر هنا.

من المثال أعلاه:

  • إن العناصرغير الثابتة Non-static قد تكون عامة (public) أو خاصة (private).
  • أن المتغيرات غير الثابتة الـ Non-static Variables تمثل الـ Instance variables.
  • الدوال الغير ثابتة Non-static Methods قد تكون من الدوال التي ترجع قيم والدوال التي لا ترجع قيم (void) .
  • يمكن الوصول للعناصر غير الثابتة Non-static بواسطة الـ Object.
  • القيم في العناصر الغير ثابتة (non- static) خاصة لكل Object لا حظ عدم التغير على قيمة المتغير circle_num (مما يعني أن في كل مرة يتم إنشاء object يتم إنشاء نسخة جديدة من هذا المتغير).

العناصر الثابتة (Static-members)

العناصر الثابتة Static-members هي المتغيرات Variables والدوال Methods التي تحتوي على كلمة static في بيان الإعلان عنها. ترتبط هذه العناصر مع الـ Class القيم في المتغيرات من هذا النوع تشير إلى نفس الموقع في الذاكرة (Reference) في جميع الـ Objects الخاصة بهذا الـ Class. ويتم الوصول للعناصر الـ static بواسطة الـ Class المثال التالي يوضح استخدامها:

في Circle Class نضيف متغيرات ودوال من نوع Static :


...........
public class Circle {
    //declaring  static variables
    private static int circle_num = 0; 
  	public static double redius;
    //constructos
    public Circle (){
      circle_num++;
    }
    public Circle (double r){
      redius = r;
      circle_num++;
    }
  	//Static Methods for calculate circumference and area 
  	private static double Circumference() { return 2 * 3.14 * redius; }
  	private static double Area()  {return 3.14 * redius * redius; }
    //A static method for printing the output
    public static void CircleInfo(){
      Console.WriteLine("Circle number is:{0}\nCircle circumference is:{1}\nCircle area is:{2}", circle_num , Circumference() ,Area());
    }
  }//end class Circle
...........

في الـ Class الخاص بالتنفيذ نقوم بإنشاء اكثرمن Object كتالي:


...........
public static void Main(string[] args)
		{
		  //Create thefirst object 
		  Circle circle1 = new Circle(5);
		  //call the static method via class name  
		  Circle.CircleInfo();
		  //Create the second object 
		  Circle circle2 = new Circle();
      //Access to static vriables
      Circle.redius = 3;
		  Circle.CircleInfo();	
		}
...........

الـ Output للمثال:

Circle number is:1
Circle circumference is:31.4
Circle area is:78.5
Circle number is:2
Circle circumference is:18.84
Circle area is:28.26

المثال متوفر بالكامل متوفر هنا.

من المثال أعلاه:

  • إن العناصر الثابتة (static-members) قد تكون عامة (public) أو خاصة (private).
  • يمكن الوصول للعناصر الثابتة Non-static بواسطة اسم الـ Class.
  • الدوال ثابتة Static-Methods قد تكون من الدوال التي ترجع قيم والدوال التي لا ترجع قيم (void) .
  • القيم في المتغيرات الثابتة (static) على مستوى الـ Class لاحظ قيمة المتغير Circle_num، في المرة التي أولى التي تم إنشاء الـ Object أعطى قيمة 1 وأعطى قيمة 2 للـ Object الثاني مما يعني أن مرجعية قيمته ثابتة فهو هنا يشير الى موقع ثابت في الذاكرة لا يتغير مع تعدد الـ Objects.

في الأمثلة أعلاه نرى النتائج للدوال الثابتة Static -method تتطابق مع نتائج الدوال غير الثابتة non-static وهو طبيعي فالدوال تتعامل مع نسخها الخاصة من المتغيرات وليس مع المرجع الفعلي للمتغير على الذاكرة.

تمييز العناصر الثابتة Static-members ايضاً بعدد من المميزات منها مايلي :

  • العناصر الثابتة تتعامل فقط مع بعضها البعض ، فمثلاً الدوال من نوع static لايمكن ان تستدعي دالة من نوع non-static ، ايضاً لا يمكن أن تشير متغير non-static.
  • لا يمكن استخدام الكلمات مثل (this/ super ) للإشارة الى العناصر الثابتة static-members .


تعدد الـ Constructor

المنشئ او الـ Constructor هو دالة خاصة يتم استدعاؤها "تلقائيًا" في وقت إنشاء الـ object. يستخدم الـ Constructor عادةً لتهيئة الكائنات بقيم افتراضية ما لم يتم توفير قيم مختلفة. يحمل الـ Constructor نفس اسم الـClass . الـ Constructor لا يرجع قيم. ويمكن أن يحتوي الـClass على أكثر من Constructor طالما أن لكل منها توقيع مختلف (أي بناء جملة مختلف الإدخال في كل مرة -Different arguments ). المزيد عن الـ Constructor في مقال مقدمة عن Classe & object .

في لغة برمجة مثل  C#  يعد استخدام الـ Constructor مع الـ Class مهم جداً وتوفر عدد من منها في الـ Class يتيح للـ class التعامل مع سيناريوهات متعددة لاستقبال البيانات، فمثلاً يمكن للمستخدم إنشاء الـ Object بالقيم الافتراضية ومن ثم يمكنه ادخال قيمة الخاصة في وقت لاحق، فلا يجبر المستخدم على اكمال كامل البيانات للـ object لحظة الإنشاء .

تعدد الـ constructor يعطى مرونة أكثر للبرنامج، كما ان الـ compiler يستطيع التعرف على أي من الـ constructors يستوجب استدعاءه لحظة انشاء الـ Object، بناء على عدد ونوع وترتيب البيانات المدخلة، فالـ compiler يتعامل تعدد مع الـ constructor بناء على مفهوم الـ overloading (المزيد عن الـ overloading في مقال عن التعامل مع الدوال في سي شارب).

نلاحظ استخدام تعدد الـ constructors في الأمثلة السابقة و في هذا المثال نرى كيف يحقق تعدد الـ constructor مبدأ تعدد الأشكال Polymorphism:


...........
public class Students{
	int age;
    string name;
    public Students(){
    	age = 0;
    	name = "unknown";
        Console.WriteLine("Parameter less Constructor");
        Console.WriteLine(ToString());
      }
    public Students(int a, string n){
        age = a;
        name = n;
        Console.WriteLine("Constructor with parameters");
        Console.WriteLine(ToString());
    	}
     public override string ToString(){
        return string.Format("[Students Age ={0}, Name={1}]", age, name);
        }
    }//end class Students
class StudentsTest{
        public static void Main(string[] args){
            Students st1 =new Students();
            Students st2 = new Students(18, "Tagreed");
            Console.ReadLine();
        }	
    }
...........

المثال متوفر بالكامل متوفر هنا.

يجب أن يحتوي كل classe على constructor واحد على الأقل فعدم توفر أي constructor فيالـ class ،يعني أن يقوم الـ compiler بإنشاء constructor الإفتراضي الذي لا يأخذ أي Parameters عند استدعائه. في المقابل عند اضافة  constructor واحد على الأقل لن يقوم الـ compiler بإنشاء الـ constructor الإفتراضي للـ class .

إذا كان الـ class يحتوي على أكثر من constructor ولكن لا يوجد أي منها بدون parameters وحاول أحد التطبيقات استدعاء constructor بدون parameters لتهيئة object ، سيحدث خطأ في التجميع. فلا يمكن استدعاء constructor بدون arguments فقط إذا لم يكن للـ class أي constructor .



استخدام الكلمة الأساسية this

توفر سي شارب الكلمة الأساسية "this" التي تشير إلى أن هذا المتغير خاص بالـ Object .فإذا كانت أسماء الـ parameters للـ constructors متطابقة مع أسماء instance-variable ، فإنها تخفي instance-variable المقابلة. أي استخدام نفس الاسم للمتغير لتمثيلة داخل دالة أو constructor يخفي المتغير، لهذا يمكن استخدام this للإشارة أننا نعني هنا المتغير الذي على مستوى الـ Object وليس النسخة الحالية للدالة.

وتتم كتابة this قبل اسم المتغير ويفصل بينها وبين اسم المتغير بنقطة كتالي:

 this.varableName;

ويوضح المثال التالي استخدامها:


...........
public class Students{
	int age;
	string name;
	//using "this" keyword to refer instance variables	
	public Students(){ 
		this.age = 0;
		this.name ="unknown";
	}
	//OR using short formula to "this"
	//public Students():this (0, "unknown"){ }
...........

كما يمكن استخدامها مع الدوال:


...........
public class Time1{
    public int hour; //0-23
    /*If method's variable has same name the instance variable of class, 
    "this" here refers to the method's variables */
    public void SetTime(int hour){
        //without using "this" we get the wrong result
        /*hour = ((hour >= 0 && hour < 24) ? hour:0);  */ // Erorr output>> 0 
        this.hour = ((hour >= 0 &&  hour < 24) ? hour:0);  //output>> 10
    }
  }//end class Time1
...........

الأمثلة لهذا الجزء متوفرة بالكامل هنا.

نذكر هنا أن this تعمل فقط مع المتغيرات غير الثابتة (Instance variables ) .



استخدام Readonly

توفر لغة  C#  الكلمة الأساسية readonly في تعريف متغيرات الـ Class لتحدد أن المتغير للقراءة فقط (غير قابل للتعديل وأن أي محاولة لتعديله بعد تعيين القيمة الأولية له  تعد خطأ)  تماماً مثل الثوابت (const) .

ويتم إعلان المتغيرات readonly بأحرف كبيرة. ويمكن تهيئة متغيرات readonly عند إعلانها، ولكن هذا ليس مطلوبًا. لا يصبح متغير الـ class المعرف بـ readonly غير قابل للتعديل إلا بعد أن يكمل constructor التنفيذ. حيث يتم تعيين القيمة الاولية والأخيرة لهذا النوع من المتغيرات.

لنرى المثال التالي يوضح طريقة استخدام readonly مع الـ Instance variables


...........
 public class Increment {
        public readonly int INCREMENT;
	
		public Increment(int IncrementValue)
		{
			INCREMENT = IncrementValue;
		}
		//Any changing after primmentive value is error 
		/*
		public ModiftReadonly(){
		  INCREMENT ++;
		}*/
	}
...........

المثال متوفر بالكامل متوفر هنا.

الفرق بين استخدام const واستخدام readonly

على الرغم من أن const وreadonly يبدوان متشابهين، إلا أن هناك بعض الاختلافات الرئيسية بينهما:

  • تستخدم readonly كجزء من الإعلان عن العنصر بينما const تستخدم للإعلان عن ثابت Constant.
  • تعمل readonly، مع أنواع متعددة من العناصر مثل متغيرات instance variables والدوال methods والهياكل struct.
  • يجب تهيئة Initialization (تعيين القيمة الأولية) الثابت const في وقت الإعلان، بينما يمكن تهيئة متغير readonly في وقت الإعلان أو في جزء لاحق من البرنامج مثلاً في الـ constructor.
  • قد يكون للثوابت const نطاق عام ويمكن استخدامها في أي مكان في الكود، بينما تقتصر متغيرات readonly على النطاق الذي الذي تم إعلانها فيه سواء كانت داخل method أو class .
  • يتم تقييم الثوابت Constants في وقت التجميع (compile time)، بينما يمكن تقييم متغيرات readonly في وقت التشغيل(Runtime).


 في ختام هذا المقال يمكن القول أن الفهم العميق لاستخدامات الـ Class و Object في سي شارب يوفر أساسًا قويًا لتطوير تطبيقات برمجية فعالة وقابلة للتوسع. من خلال التمييز بين العناصرالثابتة Static وغير الثابتة Non-static، يمكنك تحسين إدارة الموارد والأداء. كذلك، يتيح تعدد الـ Constructor طرقًا مرنة لإنشاء الكائنات، بينما تعزز الكلمة الأساسية this من وضوح الكود وتفاعله. بالإضافة إلى ذلك، يضمن استخدام Readonly حماية القيم من التغيير غير المقصود. هذه المفاهيم مجتمعة تعزز من قدرتك على كتابة كود نظيف ومنظم، مما يسهم في إنشاء تطبيقات قوية وموثوقة.

إرسال تعليق

فضلاً اترك تعليق
موافقة ملفات تعريف الارتباط
لتحسين تجربتك… يستخدم موقعنا ملفات تعريف الارتباط (Cookies)
Oops!
It seems there is something wrong with your internet connection. Please connect to the internet and start browsing again.
AdBlock Detected!
We have detected that you are using adblocking plugin in your browser.
The revenue we earn by the advertisements is used to manage this website, we request you to whitelist our website in your adblocking plugin.
Site is Blocked
Sorry! This site is not available in your country.