تقييم الموضوع :
  • 0 أصوات - بمعدل 0
  • 1
  • 2
  • 3
  • 4
  • 5
الفصل(12): Oop بالتفصيل...الجزء الثاني
#1
بسم الله الرحمن الرحيم
السلام عليكم ورحمة الله وبركاته

نبدا من حيث انتهينا من الفصل السابق
يجب قراءة الفصل السابق لتتمكن من الاستمرار في هذا الفصل
الفصل 11

وهذا الفصل ايضا كتب بقلم الاستاذ احمد نجم


وراثة الواجهاتInterface Inheritance

تحدثنا سالفاً عن اشتقاق او وراثة فئة من أخرى وفيها تورث الفئة المشتقة كافة خصائص ووسائل وأحداث الفئة الأب وكذلك أيضاً وراثة الكود المكتوب بالداخل كاملاً. يُمكنك Visual Basic .NET من تعريف أو التصريح عن الواجهات ، والواجهة ما هي إلا واجهة لفئة ما واسمها خير دليل على هذا وهي لا تحتوي على أية أكواد للتنفيذ. بعد تصريحك عن واجهة جديدة يمكنك استخدام الكلمة [FONT=&amp]Implements[/FONT][FONT=&amp]<InterfaceName>[/FONT] وذلك كي تشتق أو تستدعي كافة الوسائل والخصائص والأحداث التي تم التصريح عنها داخل الواجهة.

كي تتضح لديك الرؤية أكثر من ذلك ، اتبع ما يلي ... قم بالتصريح عن هذين المتغيرين كما هو موضح أدناه :
كود :
[align=left]Dim CN1 As New System.Data.OleDb.OleDbConnection
[/align]


العجيب في هذين التصريحين أنك إذا نظرت في الوسائل والخصائص المصاحبة للكائن [FONT=&amp]CN1[/FONT] ستجدها بنفس الترتيب ونفس الهجاء بالنسبة للكائن [FONT=&amp]CN2[/FONT] ، ولكن مع اختلاف الوظيفة ... يعني مثلا الوظيفة [FONT=&amp]Open[/FONT] فهي مصاحبة لكلا الكائنين ولكنها مع [FONT=&amp]CN1[/FONT] تتصل بأي قاعدة بيانات حسب جملة الاتصال الممررة إليها [FONT=&amp]Connection[/FONT][FONT=&amp]String[/FONT] ، أما مع الكائن [FONT=&amp]CN2[/FONT] فهي لا تتعامل إلا مع محركات قواعد بيانات [FONT=&amp]MS[/FONT][FONT=&amp]SQL[/FONT][FONT=&amp]Server[/FONT] فقط بالرغم من أن اسم الوظيفة واحد في كلا الكائنين ... هنا يتضح معنى الواجهات.
سأوضح لك مرة أخرى وبمثال آخر .. بفرض أنك مدير مشروع برمجي معين وليكن هذا المشروع خاص بصناعة مكتبة DLL للتعامل مع ملفات MS OFFICE ، وقد قررت كمدير مشروع أن تقوم بعمل أربعة فئات [FONT=&amp]4[/FONT][FONT=&amp]Classes[/FONT] ، الأولى منهم لـ MS Word والثانية لـ MS Access والثالثة لـ MS PowerPoint والرابعة لـ MS Excel ، وتم الاتفاق على عدة وظائف مثلا كالآتي :
  • [FONT=&amp]Method [/FONT][FONT=&amp]>> [/FONT][FONT=&amp]OpenFile[/FONT]
  • [FONT=&amp]Method [/FONT][FONT=&amp]>> [/FONT][FONT=&amp]DeleteFile[/FONT]
  • [FONT=&amp]Property >> FileName[/FONT]
  • [FONT=&amp]Method [/FONT][FONT=&amp]>> FileSize[/FONT]

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





من القائمة Project اختر العنصر Add Component ثم اختر العنصر Interface كما هو موضح بالصورة أدناه :

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


كود :
[align=left]Public Interface MyInterface
'This subroutine to open the file by using [FileName] property value  
    Sub OpenFile()
    'Use this property to specify file path or read the file path to open it or delete it
    Property FileName() As String
    'This subroutine to delete the file by using [FileName] property value
    Sub DeleteFile()
    'This function used to return the file size by using [FileName] property value

    Function FileSize() As Double
End Interface[b][FONT=Tahoma]
[/FONT][/b][/align]




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

كود :
[align=left]Implements MyInterface[b][FONT=Tahoma]
[/FONT][/b][/align]



ستجد نفسك في الفئة مثلا الخاصة بالـ MS Excel قد حصلت على النتيجة التالية كوراثة حقيقية لما تم التصريح عنه في الواجهة [FONT=&amp]MyInterface[/FONT]:

كود :
[align=left]Public Class Excel  
Implements MyInterface    
     Public Sub DeleteFile() Implements MyInterface.DeleteFile    
End Sub
     Public Property FileName() As String Implements MyInterface.FileName
         Get
        End Get

        Set(ByVal value As String)
        End Set
End Property
    Public Function FileSize() As Double Implements MyInterface.FileSize
    End Function
    Public Sub OpenFile() Implements MyInterface.OpenFile
    End Sub
  End Class
[/align]



هذه هي بالفعل شكل الفئة بعد وراثة الواجهة وما عليك إلا توزيع الهيكل العام لهذه المكتبة DLL على المطورين في المشروع وهم يقوموا بكتابة الكود فقط داخل الوسائل والخصائص والأحداث المصرح عنها ... يمكنك تحميل المشروع من الرابط التالي :
http://www.4shared.com/rar/8gCjzUtj/21250864124.html

أو من المرفقات بإسم : مرفق 1

** ملحوظة **
كما ذكرنا سابقاً أن Visual Basic .NET لا يسمح لك بالوراثة من أكثر من فئة ، ولكن داخل الفئة الواحدة يمكنك وراثة أكثر من واجهة.

كلمة أخيرة في مبدأ الوراثة .. الكلمات المفتاحية
[FONT=&amp]Access Modifiers[/FONT]
  • [FONT=&amp]Public[/FONT]: يجعل المتغير أو الوسيلة معرفة على مستوى الفئة ككل وكذلك على مستوى المشروع بالكامل ، كما يمكنك الحصول على هذا المتغير أو هذه الوسيلة إذا قمت بأخذ نسخة Instance من الفئة في أي مكان آخر على اختلاف نوع المشاريع سواء ******sApplications أو ClassLibrary ... الخ. كما أن هذا المتغير أو الوسية من النوع [FONT=&amp]Public[/FONT] تظهر في حالات الوارثة في الفئات المشتقة.
  • [FONT=&amp]Friend[/FONT]: يجعل الإجراء معرف على مستوى الفئة ككل وداخل المشروع الحالي بصفة عامة ، لكن اذا تم دمج الفئة في ملف DLL وأخذ نسخة لكائن من الفئة فإن الاجراءات من هذا النوع لا تظهر.
  • [FONT=&amp]Default[/FONT]: وهنا نحن بصدد الحديث عن عدم استخدام الكلمات المفتاحية والتي يعتبرها المترجم من أنها من النوع [FONT=&amp]Public[/FONT] وينطبق عليها ما ورد سابقاً.
  • [FONT=&amp]Private[/FONT]: يجعل الإجراء معرف على مستوى على الفئة فقط ، ولا يظهر في أي مكان خارجها.
  • [FONT=&amp]Protected[/FONT]: يشبه الـ [FONT=&amp]Private[/FONT] تماماً ولكن يختلف عنه في نقطة ، ألا وهي أنه في حالة التوريث فإن الفئة المشتقة [FONT=&amp]Derived[/FONT][FONT=&amp]Class[/FONT] يظهر بداخله الإجراءات والمتغيرات من النوع [FONT=&amp]Protected[/FONT] ، ولكن إذا أخذت نسخة من الفئة الأب [FONT=&amp]****[/FONT][FONT=&amp]Class[/FONT] أو ما يسمى بالـ [FONT=&amp]Parent[/FONT][FONT=&amp]Class[/FONT] فلن تظهر المتغيرات ولا الإجراءات من النوع [FONT=&amp]Protected[/FONT].



يمكنك مراجعة المثال التالي ، فهو عبارة عن فئة بالاسم ( MyClass ) وبها بعض الإجراءات باختلاف الكلمات المفتاحية لكل منها:
http://www.4shared.com/rar/pmYpsxLx/31250864124.html

أو من المرفقات بإسم : مرفق 2




الملفات المرفقة
.rar   مرفق 1.rar (الحجم : 55.41 ك ب / التحميلات : 42)
.rar   مرفق 2.rar (الحجم : 10.8 ك ب / التحميلات : 42)
الرد }}}
تم الشكر بواسطة:
#2
التعدد [ [FONT=&amp]Polymorphism[/FONT] ]
من أجمل ما قرأت عن التعدد أو الـ [FONT=&amp]Polymorphism[/FONT] كان ذلك في كتاب ( Visual Basic 2008 ) لكاتبه Rod Stephens كان الآتي بالنص :
Roughly speaking, polymorphism means treating one object as another. In OOP terms, it means that you can treat an object of one class as if it were from a parent class.

فعلا هكذا ، أثناء تعرضك للتعدد أو الـ [FONT=&amp]Polymorphism[/FONT] فأنت يمكنك معاملة الكائن كما لو كان كائن آخر .. على سبيل المثال فلنفترض افتراضاتنا السابقة وهي أنه لدينا الفئة المسماة [FONT=&amp]Employee[/FONT] وكذلك الفئة [FONT=&amp]Customer[/FONT] وهما مشتقان من الفئة الأب المسماة [FONT=&amp]Person[/FONT]. من هنا يمكنك معاملة الكائنات المصاحبة للفئتين [FONT=&amp]Employee[/FONT] وكذلك [FONT=&amp]Customer[/FONT] كما لو انك تتعامل مع كائنات الفئة الأب [FONT=&amp]Person[/FONT] وذلك لأنهم بكل بساطة للفئة الأب وليس الابن كما يظهر لك. يعني هذا انك ظاهرياً تتعامل مع الفئات [FONT=&amp]Customer[/FONT] و [FONT=&amp]Employee[/FONT] ولكن تستخدم هاتين الفئتين كجسر من خلاله تتعامل في الباطن مع كائنات الفئة الأب [FONT=&amp]Person[/FONT].
يُمكنك الـ [FONT=&amp]Visual[/FONT][FONT=&amp]Basic .NET[/FONT] من تعيين أو تخصيص قيمة من فئة مشتقة إلى متغير في الفئة الأب. في المثال التالي يمكنك أن تضع كائني [FONT=&amp]Employee[/FONT] أو [FONT=&amp]Customer[/FONT] في متغير من الفئة الأب ... اتبع الكود ثم تابع رابط المشروع في الأسفل :

كود :
[align=left]Dim emp As New Employee   'Create an Employee.  
Dim cst As New Customer   'Create a Customer.
Dim per As Person         'Declare a Person variable.
per = emp                 'Ok .. An Employee is a Person.
per = cst                 'Ok .. A Customer is a Person.

emp = per                 'Not Ok .. A Person is not necessarily an Employee.
[/align]

يمكنك تحميل المشروع من الرابط التالي :
http://www.4shared.com/rar/kbnuyugP/11250864124.html
أو من المرفقات بإسم : مرفق 3
** ملحوظة **
يمكنك الوصول للمعالم أو المكونات المُعرفة الخاصة بنوع المتغير الذي تستخدمه للإشارة إلى كائن آخر. هذا يعني أنك مثلاً لو لديك متغير من النوع [FONT=&amp]Person[/FONT] يشير إلى كائن من النوع [FONT=&amp]Employee[/FONT] فإنك فقط تستطيع الاستفادة من معالم الفئة [FONT=&amp]Person[/FONT] وليس لك الحق في الاستفادة مما تم إضافته على الفئة [FONT=&amp]Employee[/FONT] بعد الوراثة.

اعادة التعريف[FONT=&amp]Overloading[/FONT]
ماذا لو أنك قمت بتصميم فئة Class وأردت عمل إجراء فرعي Subroutine بالاسم [FONT=&amp]InsertPersonData[/FONT] ، وهذا الإجراء الفرعي يحتوي على الباراميترات أو المعاملات الآتية :
  • [FONT=&amp]FirstName[/FONT]
  • [FONT=&amp]LastName[/FONT]
  • [FONT=&amp]Age[/FONT]
  • [FONT=&amp]Address[/FONT]
  • [FONT=&amp]EMail[/FONT]
  • [FONT=&amp]MobileNumber[/FONT]
المعاملان ( FirstName , LastName ) يعدان من المعاملات الإجبارية Not Optional Parameter ، أما عن بقية المعاملات فهي اختيارية حسب المتوفر لدى مستخدم الإجراء [FONT=&amp]InsertPersonData[/FONT] ، ولو تخلينا عن مبدأ الـ Overloading ضمن مبادئ الـ OOP فسيكون شكل الإجراء الفرعي كالآتي :

كود :
[align=left]
Public  Sub InsertPersonData(ByVal FirstName As String, ByVal LastName As  String, Optional ByVal Age As Integer = 20, Optional ByVal Address As  String = "", Optional ByVal EMail As String = "", Optional ByVal  MobileNumber As String = "")
'---------------------------
'Your Convenient Code Lines
'---------------------------  
End Sub
[/align]

فقد قمنا في الإجراء السابق بجعل بقية الاختيارات من النوع [FONT=&amp]Optional[/FONT] ولكن للأسف وبكل أسف ستجد أن المعاملات من النوع [FONT=&amp]Optional[/FONT] يجب أن تحتوي على قيم مبدئية وهذا نصاً للاعتراض الذي يصدره الـ Visual Basic .NET بالنص الآتي :
[FONT=&amp]Optional parameters must specify a default value[/FONT]

ولو طبقنا هذا الاعتراض في مثالنا الحالي فسنجد مثلا أننا قمنا بتعريف المتغير [FONT=&amp]Age[/FONT] على أنه متغير رقمي من النوع [FONT=&amp]Integer[/FONT] ونوعه اختياري [FONT=&amp]Optional[/FONT] وقيمته الافتراضية = 20 ، وهذا يعني أن المستخدم لهذا الإجراء لن يستطيع الاستفادة من هذا الإجراء لأنه لو لم يقوم بإدخال عمر الشخص فان البرنامج يقوم بشكل افتراضي بوضع القيمة 20 في حقل العمر في حين أن المستخدم للإجراء لا يعرف أو لم يتوفر لديه أية بيانات عن عمر الشخص.
أعتذر لو استطردت كثيراً في وصف المشكلة ، ولكن هنا يأتي دور الـ Overloading ، فهل تعلم أن الـ Visual Basic .NET يعطيك إمكانية تكرار أو إنشاء أكثر من وسيلة Method بنفس الاسم ولكن بشرط اختلاف المعاملات. أي أنك من الممكن مثلاً أن تقوم بإنشاء الإجراء السابق المسمى [FONT=&amp]InsertPersonData[/FONT] أكثر من مرة وبنفس الاسم ولكن يختلف في المعاملات الممررة إليه. بالطبع أثناء استخدامك للغات الـ .NET لاحظت الآتي :


إذا نظرت إلى ما يشير إليه السهم في الصورة السابقة ستجد الرمز الآتي ([FONT=&amp]1 of 12 [/FONT]) وهذا يعني بكل بساطة أن الإجراء أو الوسيلة المسماة [FONT=&amp]Input[/FONT] موجودة داخل الـ .NET Framework اثنتي عشرة مرة ولكن مع اختلاف المدخلات أو المعاملات وهذا تطبيق حي للـ Overloading.
تعال معي نضرب مثلاً آخر .. الفئة المسماة [FONT=&amp]Person[/FONT] يظهر فيها إجراءان كإجراءات مشيدة للفئة Constructor Subroutines بالاسم New. الإجراء المشيد الأول لا يأخذ أية معاملات بينما الإجراء المشيد الثاني يأخذ المعاملان المتغيران ( [FONT=&amp]FirstName[/FONT] , [FONT=&amp]LastName[/FONT] ) كقيم افتراضية أثناء أخذ نسخة Instance من الفئة. وسيكون شكل الفئة Person بعد كتابة الكود كما يلي :

كود :
[align=left]Public Class Person
    Public FirstName As String
    Public LastName As String
    Public Sub New()
        FirstName = "<fname>"
        FirstName = "<lname>"
    End Sub
    Public Sub New(ByVal first_Name As String, ByVal last_Name As String)
        FirstName = first_Name
        LastName = last_Name
    End Sub
End Class
[/align]

وإذا ذهبت للنموذج وقمت بأخذ نسخة من هذه الفئة سيظهر لديك الشكل التالي :





وهنا تضح فائدة الـ
Overloading فبدلاً من استخدام المعاملات الاختيارية Optional Parameters وكذلك حالات الشرط IF Conditions ، فنلجأ حينئذ لمثل هذه الطرق والتي تحل مشاكل كثيرة. وفيما يلي مثال صغير عن أخذ نسختين وإسنادهما للكائنات [FONT=&amp]Person_1[/FONT] وكذلك [FONT=&amp]Person_2[/FONT] كما يلي :

كود :
[align=left]Dim Person_1 As New Person
Dim Person_2 As New Person("Ahmed", "Negm")
[/align]
يمكنك تحميل المثال من الرابط التالي :
http://www.4shared.com/rar/kbnuyugP/11250864124.html
أو من المرفقات بإسم : مرفق 4


ولكن هل جاء بذهنك أخي القارئ ما هي ميكانيكية تحديد الإجراء ، يعني مثلاً أنه لدينا ثلاثة إجراءات بالاسم [FONT=&amp]New[/FONT] وبالطبع كما ذكرنا أن لكل منهما معاملاته الخاصة التي تختلف عن المعاملات الخاصة بنظائره ، فكيف أقوم بتحديد التعامل مع الأول أو الثاني أو الثالث ... الخ ؟. هنا يقوم الـ Visual Basic .NET بتحديد الإجراء حسب نوعية وعدد الإجراءات الممررة إليه وليس عليك أية التزامات تجاه هذه الجزئية.

** ملحوظة مهمة جدا **
عند استخدامك للدوال أو ما يسمى بالـ Functions ، فيكون نفس ما تمرسنا عليه في الإجراءات مع الـ Overloading هو نفسه مع الـ Functions ، إلا أنه يوجد جزية هامة يجب التنويه عنها.
من البديهي أن يدور بذهن أحدكم فيما يخص الـ Functions أنه إذا تم تغيير نوع الدالة أو ما يسمى بالـ Return Type فهذا يحقق الـ Overloading ... !!! ، وهنا سأصدمك بلا شك وأقول لك لن يحدث هذا ، فتحقيق الـ Overloading مع الدوال لا يأتي بتغيير نوع الدالة فقط ، ولكن لابد تحقق شرط آخر وهو اختلاف المعاملات. انسخ الكود التالي في محرر Visual Basic .NET واقرأ نص الاعتراض بنفسك :
كود :
[align=left][b][FONT=Tahoma]
[/FONT][/b]Function MySum(ByVal FirstNumber As Double, ByVal SecondNumber As Double) As Double
Dim x As Double
x = FirstNumber + SecondNumber
Return x
End Function
'-------------------------------------------'
Function MySum(ByVal FirstNumber As Double, ByVal SecondNumber As Double) As Integer
Dim x As Integer
x = FirstNumber + SecondNumber
Return x
End Function
[/align]
وكي لا أرهقك في القراءة من المحرر فنص الخطأ يفيد الآتي : " لا يمكن أن تتعدد الدالة cannot overloaded each other وذلك لاختلافهم فقط في النوع Return Type". أما إذا أردت تصحيح الأوضاع فإليك الكود الصحيح :

كود :
[align=left]Function MySum(ByVal FirstNumber As Double, ByVal SecondNumber As Double) As Double
Dim x As Double
x = FirstNumber + SecondNumber
Return x
End Function
'-------------------------------------------'
Function MySum(ByVal FirstNumber As Integer, ByVal SecondNumber As Integer) As Integer
Dim x As Integer
x = FirstNumber + SecondNumber
Return x
End Function
[/align]
** تم إضافة الدالة المسماة MySum إلى المثال OOP4 **

والان بحمد الله تم الانتهاء من الOOP بنوع من التفصيل المجمل

ملاحظة:جميع الامثلة صممت ببرنامج ال VB2008.NET
وملاحظة اخرى: يعدكم الاستاذ احمد نجم باصدار كتاب عن الOOP قريبا ان شاء الله

بالتوفيق
دمتم بود




الملفات المرفقة
.zip   مرفق 3.zip (الحجم : 58.74 ك ب / التحميلات : 44)
.rar   مرفق 4.rar (الحجم : 53.72 ك ب / التحميلات : 44)
الرد }}}
تم الشكر بواسطة:
#3
بارك الله فيكم اخواني على المجهودات الطيبة
ولكن في الحقيقة لم افهم الكثير ربما لاني مبتدئ والدرس يعتبر لفئة متقدمة
الرد }}}
تم الشكر بواسطة:
#4
بارك الله فيك
الرد }}}
تم الشكر بواسطة:


المواضيع المحتمل أن تكون متشابهة .
الموضوع : الكاتب الردود : المشاهدات : آخر رد
  الفصل(8): الدوال والاجراءات B3dak Hbebe 3 19,655 15-08-18, 09:20 AM
آخر رد: nagoma
  الفصل(9):مدخل الى الفئاتClasses - الجزء الأول B3dak Hbebe 5 4,326 30-05-17, 01:09 PM
آخر رد: ali hussein
  الفصل(5):صنع القرار...الجزء الأول-الجمل الشرطية Omar Mekkawy 4 4,166 10-08-13, 05:39 PM
آخر رد: Omar Mekkawy
  الفصل(3): التركيبات أنواعها واستخداماتها Omar Mekkawy 4 4,154 10-08-13, 05:32 PM
آخر رد: Omar Mekkawy
  الفصل (1) : الفيجوال بيسك دوت نت (لمحة تعريفية) Omar Mekkawy 2 3,491 27-07-13, 02:39 PM
آخر رد: green.grass52
  الفصل (0) : دورة تعلم معنا فيجوال بيسك دوت نيت Omar Mekkawy 7 4,821 18-07-13, 06:29 PM
آخر رد: el@nsary
  الفصل(16): مدخل لمسارات التنفيذ Threading B3dak Hbebe 3 3,777 27-04-13, 10:58 AM
آخر رد: خليل اسماعيل
  الفصل(15): الفئتان Stack و Queue B3dak Hbebe 2 3,220 27-04-13, 09:20 AM
آخر رد: خليل اسماعيل
  الفصل (11) :oop بالتفصيل ..الجزء الاول Easy4ever 3 3,568 27-04-13, 09:08 AM
آخر رد: خليل اسماعيل
  الفصل(10):مدخل الى الفئات..الجزء الثاني B3dak Hbebe 2 3,203 27-04-13, 08:59 AM
آخر رد: خليل اسماعيل

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


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