تقييم الموضوع :
  • 0 أصوات - بمعدل 0
  • 1
  • 2
  • 3
  • 4
  • 5
الدرس السادس عشر : ال OverLoading
#1
منقول من المنتدؤ القديم
كاتب المقال احمد جمال المشرف العام

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

من اهم مبادئ ال OOP هي تطبيق مبدئ ال Overloading ، حيث يمكن تسمية عدة طرق او دوال بنفس الاسم ما دام هناك تغيير في البارميترس .

ابسط مثال على عمليات ال Overloading هي دالة MessageBox.Show() في ال Windows Forms .
لو جربت ستجد هذه الأوامر مثلاً :
كود :
MessageBox.Show(string text);
MessageBox.Show(string text,string caption);
MessageBox.Show(string text, string caption, MessageBoxButtons buttons);

وغيرها ايضاً ضمن 7 اوامر ، كل واحدة منها عبارة عن دالة خاصة ولهم جميعاً نفس الاسم ، لنتصور لو لم يكن مبدأ Overloading موجوداً ، كنا سنضطر لكتابة دوال بالشكل التالي :

كود :
ShowWithString
ShowStringAndCaption
ShowStringAndCaptionAndButtons

أما الآن ولتسهيل الاستخدام تجدهم جميعاً بنفس الاسم ، وهذا ما يسبب سهولة الاستخدام .

لتطبيق مبدأ ال OverLoading في دوالك يمكنك كتابة كود بالشكل التالي - لعملية الجمع مثلاً في حين انك لا تدري هل يمرر لك في الكلاس قيم من نوع int او من نوع double - :

C#:

كود :
static int Add(int x, int y) { return x + y; } static double Add(double x, double y) { return x + y; } static long Add(long x, long y)
{ return x + y; }

vb.net:
كود :
Private Shared Function Add(ByVal x As Integer, ByVal y As Integer) As Integer
    Return x + y
End Function
Private Shared Function Add(ByVal x As Double, ByVal y As Double) As Double
    Return x + y
End Function
Private Shared Function Add(ByVal x As Long, ByVal y As Long) As Long
    Return x + y
End Function

يمكن ان نعيد الكرة مرة أخرى مع ال Constructor ، فيمكنك عمل عدد منها حسب احتياج المستخدم ، لو عدنا لمثالنا Person يمكن تعريف ال Constructors بالشكل التالي :

c#:

كود :
class Person
{
public string FirstName;
public string LastName;
public int Age;

public Person()
{
Console.WriteLine("c1");
}
public Person(string fname,string lname)
{
FirstName = fname;
LastName = lname;
Console.WriteLine("c2");
}
public Person(string fname,string lname,int myage)
{
FirstName = fname;
LastName = lname;
Age = myage;
Console.WriteLine("c3");
}
}

VB.net:

كود :
Class Person
    
    
    Public FirstName As String
    
    Public LastName As String
    
    Public Age As Integer
    
    
    
    Public Sub New()
        
        
            
        Console.WriteLine("c1")
    End Sub
    
    Public Sub New(ByVal fname As String, ByVal lname As String)
        
        
        FirstName = fname
        
        LastName = lname
        
            
        Console.WriteLine("c2")
    End Sub
    
    Public Sub New(ByVal fname As String, ByVal lname As String, ByVal myage As Integer)
        
        
        FirstName = fname
        
        LastName = lname
        
        Age = myage
        
            
        Console.WriteLine("c3")
    End Sub
    
End Class

وبهذه الطريقة يمكننا انشاء كائنات بأحد الطرق التالية :

C#:
كود :
Person MyEmpolyee = new Person();
Person MyEmpolyee = new Person("ahmed","gamal");
Person MyEmpolyee = new Person("ahmed", "gamal",22);
VB.net:
كود :
Dim MyEmpolyee As New Person()
Dim MyEmpolyee As New Person("ahmed", "gamal")
Dim MyEmpolyee As New Person("ahmed", "gamal", 22)
الرد }}}
تم الشكر بواسطة:
#2
كاتب الرد
أبو عابد
متقاعدد
كنت ناوي أضع سؤال عن التحميل الزائد للدوال ولكن بما أنك تطرقت لها هنا فسوف أضع سؤالي هنا ، بعد إذنك يعني


كيف نجمع بين هذين الإجراءين في الكلاس الواحد ؟

كود :
Public Sub New(ByVal UserName As String)        
      
        _UserName = UserName

End Sub

كود :
Public Sub New(ByVal Email As String)        
      
        _Email = Email

End Sub

أعرف أن المشكلة أن كلاهما String

ولكن كيف لي أن أقوم بمثل هذا ؟
------------------------------------------
كاتب الرد
DreamNet
مبرمج متقاعد
السلام عليكم ورحمة الله وبركاته
بالنسبة للتحميل الزائد فان له ضوابط طبعا للاستعمال
http://www.devx.com/dotnet/Article/9303/1954
------------------------------------------------------------

كاتب الرد
أبو عابد
متقاعدد
و علكيم السلام ورحمة الله وبركاته

أهلاً بك DreamNet

أنت تعرف أن المشكلة أنه الإجراء المشيد للكلاس New

و لو كان غيره لأمكن تغييراسم الدالة و انتهت المشكلة .

لذلك أبحث عن طريقة لتمرير ، ولو ملتوية كهذه :
كود :
[CODE]        Sub New(ByVal intID As Integer)
            Me._ID = intID
        End Sub
        Sub New(ByVal intAge As Int64)
            Me._Age = intAge
        End Sub
[/CODE]

-------------------------------------------.
كاتب الرد
Boutemine Oualid
كبار الشخصيات
جربت كل الطرق التي أعرفها و لم أجد الحل،
حاولت بهذه الطريقة و لم تنفع أيضا
كود :
PublicClass Car
           Private _Model AsString
           Private _Name AsString

           PublicSubNew(ByVal Name AsString)

           EndSub

           PublicSubNew(ByRef Model AsString, OptionalByVal maskParam As Object = Nothing)
          EndSub
EndClass

هل من حل
-------------------------------------------------------
كاتب الرد احمد جمال
المشرف العام

للاسف لن يوجد حل فعلياً فهذا شرط اساسي في عمليات ال overloading لا يمكن تغييره ، إلا انه يمكن التحايل عليه ببعض الطرق مثل :
كود :
Public Sub New(ByVal UserName As String, ByVal Type as Integer)

حيث يتم ارسال قيمة 0 او 1 لتحديد نوع المتغير المرسل .

الحل الآخر بارسال النص مرفق في نهايته برقم /0 او /1 مثلاً .

للاسف ال Optional لا يتم الاعتبار بها في الشروط .
لو لاحظت لن تجد MessageBox.Show تحدد ال Text فقط واخر لاظهار العنوان فقط ، إنما هناك واحد لاظهار النص وآخر لاظهار كل من العنوان والنص .
إذن الحل الامثل في هذه الحالة هو تمرير بارميتر اضافي يحتوي على 0 او 1 لتحديد فيما إذا كان المرسل بريد الكتروني ام اسم .
---------------------
أبو عابد
متقاعد
توصلت لحل (ملتوي طبعاً)

في مشروعي الحالي أنا أمرر 2 بارمتر للمشيد ، ولذلك نحج معي هذا الحل
كود :
Public Class Users

    Private _Engine As Object
    Private _UseName As String
    Private _Email As String

    Sub New(ByVal Engine As Object, ByVal UseName As String)

    End Sub

    Sub New(ByVal Email As String, ByVal Engine As Object)

    End Sub
End Class
الرد }}}
تم الشكر بواسطة:



التنقل السريع :


يقوم بقرائة الموضوع: بالاضافة الى ( 1 ) ضيف كريم