تحميل الدوال الزائد
جزء من قسم Object Oriented Programming في رحلة C# على Coddy — الدرس 50 من 70.
يتيح لك تحميل الدوال الزائد (Method overloading) تعريف عدة دوال بنفس الاسم ولكن بقوائم معاملات مختلفة. يحدد المترجم (compiler) أي نسخة سيتم استدعاؤها بناءً على الوسائط (arguments) التي تقدمها.
يجب أن تمتلك كل طريقة محملة بشكل زائد (overloaded method) توقيعاً فريداً - إما عدداً مختلفاً من المعاملات أو أنواعاً مختلفة من المعاملات:
public static void Print(string message)
{
Console.WriteLine(message);
}
public static void Print(string message, int times)
{
for (int i = 0; i < times; i++)
Console.WriteLine(message);
}
public static void Print(int number)
{
Console.WriteLine(number);
}// يختار المترجم النسخة الصحيحة
Print("Hello"); // يستدعي Print(string)
Print("Hi", 3); // يستدعي Print(string, int)
Print(42); // يستدعي Print(int)يختلف التحميل الزائد (Overloading) عن المعاملات الاختيارية (optional parameters) بطريقة مهمة. فمع المعاملات الاختيارية، يكون لديك طريقة (method) واحدة تتعامل مع سيناريوهات متعددة. أما مع التحميل الزائد، فيكون لديك طرق (methods) منفصلة يمكن أن تحتوي على منطق (logic) مختلف تماماً لكل حالة.
لاحظ أن نوع الإرجاع وحده لا يجعل الدوال فريدة - لا يمكنك امتلاك دالتين تختلفان فقط فيما تقومان بإرجاعه. يجب أن تكون قائمة المعاملات مختلفة. يعد التحميل الزائد للدوال (Method overloading) شكلاً من أشكال تعدد الأشكال في وقت التجميع (compile-time polymorphism)، حيث يتم اتخاذ القرار بشأن الدالة التي سيتم استدعاؤها عند تجميع الكود، وليس عند تشغيله.
التحدي
سهللنقم ببناء فئة آلة حاسبة متعددة الاستخدامات توضح قوة التحميل الزائد للدوال (method overloading). ستقوم بإنشاء إصدارات متعددة من طرق الحساب التي تتعامل مع سيناريوهات مختلفة - من العمليات البسيطة المكونة من رقمين إلى الحسابات الأكثر تعقيدًا - وجميعها تشترك في نفس أسماء الدوال البديهية.
ستقوم بتنظيم الكود الخاص بك عبر ملفين:
Calculator.cs: قم بإنشاء فئةCalculatorفي مساحة الأسماءMathToolsمع دوال محملة بشكل زائد تشترك في الأسماء ولكنها تقبل معاملات مختلفة:Multiply- أنشئ ثلاثة إصدارات محملة بشكل زائد:- إصدار يأخذ معاملين من نوع
intويعيد حاصل ضربهما كـint - إصدار يأخذ ثلاثة معاملات من نوع
intويعيد حاصل ضربها كـint - إصدار يأخذ معاملين من نوع
doubleويعيد حاصل ضربهما كـdouble
- إصدار يأخذ معاملين من نوع
Describe- أنشئ إصدارين محملين بشكل زائد:- إصدار يأخذ
intويعيد"Integer: {value}" - إصدار يأخذ
doubleويعيد"Double: {value}"
- إصدار يأخذ
Program.cs: في ملفك الرئيسي، قم بإنشاء مثيل منCalculatorووضح كيف يختار المترجم (compiler) تلقائيًا الدالة المحملة بشكل زائد الصحيحة بناءً على الوسائط التي تقدمها.
ستتلقى أربعة مدخلات:
- العدد الصحيح الأول (مثلاً،
5) - العدد الصحيح الثاني (مثلاً،
4) - العدد الصحيح الثالث (مثلاً،
3) - رقم عشري (مثلاً،
2.5)
باستخدام الآلة الحاسبة الخاصة بك، قم بإجراء هذه العمليات واطبع كل نتيجة في سطر خاص بها:
- اضرب أول عددين صحيحين (يستخدم إصدار two-int)
- اضرب جميع الأعداد الصحيحة الثلاثة (يستخدم إصدار three-int)
- اضرب العدد الصحيح الأول والرقم العشري (يستخدم إصدار two-double)
- صف العدد الصحيح الأول (يستخدم إصدار int)
- صف الرقم العشري (يستخدم إصدار double)
على سبيل المثال، إذا كانت المدخلات هي 5، و 4، و 3، و 2.5، يجب أن يكون المخرج:
20
60
12.5
Integer: 5
Double: 2.5لاحظ كيف تستدعي Multiply و Describe بأنواع وأعداد مختلفة من الوسائط، ومع ذلك يعرف المترجم بالضبط أي إصدار يجب استخدامه في كل مرة. هذا هو تعدد الأشكال في وقت التجميع (compile-time polymorphism) قيد التنفيذ - يحدث القرار عند تجميع الكود الخاص بك، وليس عند تشغيله!
جرّب بنفسك
using System;
using MathTools;
class Program
{
public static void Main(string[] args)
{
// قراءة المدخلات
int firstInt = Convert.ToInt32(Console.ReadLine());
int secondInt = Convert.ToInt32(Console.ReadLine());
int thirdInt = Convert.ToInt32(Console.ReadLine());
double decimalNum = Convert.ToDouble(Console.ReadLine());
// TODO: إنشاء مثيل من Calculator
// TODO: استدعاء Multiply مع عددين صحيحين وطباعة النتيجة
// TODO: استدعاء Multiply مع ثلاثة أعداد صحيحة وطباعة النتيجة
// TODO: استدعاء Multiply مع العدد الصحيح الأول والعدد العشري، وطباعة النتيجة
// TODO: استدعاء Describe مع العدد الصحيح الأول وطباعة النتيجة
// TODO: استدعاء Describe مع العدد العشري وطباعة النتيجة
}
}
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس Object Oriented Programming
1أساسيات OOP
الملفات الخارجيةNamespaces والتوجيهاتمقدمة في Classes و Objectsالكلمة المفتاحية 'this'Methods والمعاملاتFields مقابل PropertiesConstructorsObject Initializersمراجعة - آلة حاسبة بسيطة4الوراثة
صيغة الوراثة الأساسية (:)الكلمة المفتاحية 'base'الكلمات المفتاحية Virtual و Overrideالأصناف المختومة (Sealed Classes)الفئة الأساسية 'object'مراجعة - هيكلية الموظفين7ميزات متقدمة
تحميل العوامل (Operator Overloading)المفهرسات (Indexers (this[]))إعادة تعريف ()ToStringدوال التوسعة (Extension Methods)ملخص - Custom List2الخصائص والأعضاء الساكنة (Static Members)
الخصائص المطبقة تلقائيًا (Auto-Implemented Properties)خصائص القراءة فقط والكتابة فقطالحقول والدوال الساكنة (Static)الفئات الساكنة (Static Classes)الأعضاء ذات البنية التعبيرية (Expression-Bodied Members)5تعدد الأشكال والواجهات (Polymorphism & Interfaces)
تعدد الأشكال: وقت التجميع مقابل وقت التشغيلالواجهة مقابل الفئة المجردة (Abstract Class)الواجهات المتعددةالواجهات الصريحةUpcasting و Downcastingملخص - حاسبة الأشكال8مفاهيم البرمجة كائنية التوجه (OOP) المتقدمة
التركيب بدلاً من الوراثةالـ Generics (الأصناف والدوال)الـ Delegates والأحداثالـ Attributes والـ Reflectionواجهة IDisposable وجملة usingأساسيات Dependency Injection