الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

بناء الفئات Classes

مغلق
بدأه كلمة الـعـرب في 20 مايو 2006 · 8 رد · 4,921 مشاهدة · في قسم الدروس والمواضيع الهامة
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

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

بم انه لايوجد في هذا المنتدى درس متخصص بالفئات Classes فكنت أود ان ابادر واضع أول درس يشرح التعامل مع الفئات.

ولكن عندما بحثت لكي اصنع درس متكامل يفيد جميع الفئات (مبتدئين , متوسطين ومحترفين) فوجدت انني لن اقدم افضل و اكثر فائدة من دروس الأستاذ تركي العسيري.

حيث ان اعضاء المتدى وضعوا موضوع يطلبون فيه درس يشرح Classes واستخدمت الرد السريع واعطيتهم عنوان موقع كتب الحاسب العربية http://www.cb4a.com الذي يستطيعوا من خلاله تحميل كتاب الاستاذ تركي العسيري "Visual Basic للجميع – نحو برمجة كائنية التوجهOOP " الذي يوجد به فصل يشرح انشاء الفئات.

ولكن بعد التمعن في الموضوع وجدت انه من الافضل وضع موضوع يشرح ذلك ليكون مرجع للاخرين فيما بعد.

  • في البداية ارجوا ان يعذرني الأستاذ تركي العسيري باعادة نشر هذا الجزء من كتابة بدون أخذ إذنه لأنني بالفعل لا أعرف كيف أتصل به.
  • الدرس عبارة عن جزء من الفصل الخامس من كتاب الأستاذ تركي العسيري "البرمجة كائنية التوجه OOP" الذي يشرح كيفية إنشاء الفئات Classes.
  • سوف يتم تقسيم الدرس الى ثلاث اقسام رئيسية:

  1. بناء الخصائص.
  2. بناء الطرق.
  3. بناء الأحداث .. القاء الأحداث.

الآن نبدأ مع شرح الأستاذ تركي العسيري:

بناء اول فئة مبسطة

والان شغل Visual Basic كي نبدأ بتصميم اول فئة تمثل شخص سنسميها

CPerson . إختر الامر Add Class Module من قائمة Project ، ومن صندوق الحوار الذي –قد- يظهر امامك، اختر الرمز Class Module وانقر على الزر Open لتظهر لك نافذة اكواد تعريف الفئة، اضغط على المفتاح [ F4 ] لعرض نافذةخصائص الفئة، وعدل خاصية الاسم من Class1 الى CPerson ، واكتب هذا الكود في الفئة:

Public sName As String
Public dBirthDate As Date

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

اذهب الى الحدث Click التابع لنافذة النموذج واكتب هذا الكود:

Private Sub Form_Click()
Dim Turki As New cPerson
Dim Khaled As New cPerson
"تركي العسيري" = Turki.sName
Turki.dBirthDate = #1/1/1900#
"خالد الابراهيم" = Khaled.sName
Khaled.dBirthDate = #1/1/1979#
Print Turki.sName, Turki.dBirthDate
Print Khaled.sName, Khaled.dBirthDate
End Sub

قمنا -في الكود السابق – بانشاء كائنين Turki و Khaled من الفئة التي صممناها للتو CPerson ، ومن ثم قمنا بتعيين قيم للخاصيتين sName و dBirthDate لكل كائن على حدة، وختمنا الكود بطباعة قيم الخصائص التابعة للكائنين Turki و .Khaled

صحيح ان الفئة السابقة لن تطبقها في حياتك البرمجية –بشكل جاد - لطباعة قيم متغيرات، الا ان الغرض الاساسي هو مجرد توضيح فكرة الفئات وطريقة استخدامها.

((رحلة العودة الى العالم الافتراضي قد بدأت))

#2

بناء الفئات

والان بعد ان عرفتك على الفكرة الاساسية من الفئات Classes سنبدأ بالتوغل في تفاصيل بناء خصائصها، طرقها واحداثها حتى تزيد من قوة الفئة.

بناء الخصائص

اذا عدنا الى مثال الفئة CPerson السابق، فسنلاحظ أن المبرمج يستطيع اسناد

أي قيمة للخاصية dBirthDate ، وقد يعطي فرصة للمستخدم بادخال العمر من خانة نص:

Turki.iAge = CDate ( Text1.Text )

المشكلة في الكود السابق، ان المستخدم بامكانه ادخال أي عدد يمثل تاريخ

ميلاد الشخص وقد يكون تاريخ لم يحل بعد، لذلك عليك التحقق من تاريخ الميلاد

في كل مرة تمكن المستخدم من ادخال قيمة للخاصية :dBirthDate

If CDate( Text1.Text ) > Date Then
”خطأ في القيمة“ MsgBox
Else
Turki. dBirthDate= CDate(Text1.Text)
End If

يعيب الكود السابق انه يلزمك بعملية التحقق من القيمة في كل مرة تريد اسناد قيمة للخاصية dBirthDate ، والحل هو باستخدام نوع خاص من الاجراءات يسمى الخصائص والتي تمثل خصائص الكائن لتحميه من القيم الخاطئة:

Private m_dBirthDate As Date
Public Property Get dBirthDate () As Date
dBirthDate= m_dBirthDate
End Property
Public Property Let dBirthDate (ByVal dNewValue As Date)
If dNewValue > Date Then
”خطأ في القيمة“ MsgBox
m_dBirthDate = Date
Else
m_dBirthDate= dNewValue
End If
End Property

ملاحظة: في الحقيقة، اظهار رسالة MsgBox من داخل الفئة – كما في الكود

السابق - يعتبر اسلوب غير احترافي وتصميم سيء جدا للفئات خاصة عندما تزيد احجامها، ويفضل ارسال رسالة خطأ بالطريقةErr.Raise بدلا من MsgBox . الا انني استخدمت الدالة MsgBoxفي المثال لتقريب الفكرة اليك.

سيناريو تنفيذ الاجراءات السابقة سيكون كالتالي : في كل مرة تقوم بتعيين او

اسناد قيمة جديدة للخاصية dBirthDate ، سيتم استدعاء الاجراءLet dBirthDate وارسال القيمة الجديدة الى المتغير dNewValue ، وفي كل مرة تقوم بقراءة قيمة الخاصية dBirthDate ، سيتم استدعاء الاجراءGet dBirthDate والذي يعود بقيمة الخاصية. بامكانك ايضا اضافة خاصية جديدة iAge دون الحاجة لتعريف متغير خاص Private لها:

Public Property Get iAge() As Integer
iAge = DateDiff("yyyy", m_dBirthDate, Date)
End Property

تلاحظ انني لم استخدم الا اجراء واحد وهو Get iAge وتجاهلت الاجراء Let iAge وذلك لاني اريد ان اجعل الخاصية iAge للقراءة فقط Read Only ، فلو حاول المبرمج تعيين او كتابة قيمة جديدة للخاصية ستظهر رسالة خطأ :Read Only Property

ممكن جدا ‘ Print Turki.iAge
رسالة خطأ ‘ Turki.iAge = 80

وبامكانك تطبيق العكس، أي استخدام الاجراء Property Let دون الاجراء Property Get لتجعل الخاصية للكتابة فقط :Write Only Property

Private m_sPassword As String
Public Property Let sPassword ( sNewValue As String)
m_sPassword = sNewValue
End Property

المزيد ايضا، يمكنك التعامل مع اجراءات الخصائص كاجراءات Sub’s او Functions عادية لتمكنها من استقبال قيم :Parameters

Private m_sAddress (2) As String
Public Property Get sAddress( iIndex As Integer) As String
sAddress = m_sAddress ( iIndex )
End Property

Public Property Let sAddress(iIndex As Integer, sNewValue As String)
m_sAddress ( iIndex ) = sNewValue
End Property

وبامكانك استدعاء الخاصية sAddress بهذه الطريقة:

”حي الوهم – شارع الحقيقة“ = ( Turki.sAddress (0
”ولاية فلوريدا – باكستان“ = ( Turki.sAddress (1
”هاتف منزل 999 “ = ( Turki.sAddress (2

وعند الحديث عن الخصائص التي تمكنك من اسناد قيم لكائنات، فعليك استخدام الاجراء Property Set عوضا عن الاجراء :Property Let

Private m_PersonParent As CPerson
Public Property Get PersonParent( ) As CPerson
Set PersonParent = m_PersonParent
End Property

Public Property Set PersonParent( ByVal objNewValue As CPerson )
Set m_PersonParent = objNewValue
End Property

مواصفات الخصائص :Property Attributes

بامكانك تعديل مواصفات الخصائص عن طريق صندوق الحوار Procedure Attributes والذي تصل اليه من القائمة Tools بعد تحريك مؤشر الكتابة الى مكان اجراء الخاصية . من هذه المواصفات: جعل الخاصية افتراضية Default Propertey ، اخفاء الخاصية من نافذة مستعرض الكائنات Object Browser ، كتابة وصف للخاصية ....الخ، بامكانك استكشاف باقي الخيارات في صندوق الحوار، وعليك ان تعلم علم اليقين ان جميع هذه الخيارات ستحفظ في ملف الفئة CLS . فقط ولن تظهر لك في نافذة محرر ا كواد الفئة، فلو قمت بعملية نسخ ولصق اكواد الفئة الى فئة اخرى، عليك اعادة عملية تحرير مواصفات الفئة.

بناء الطرق

الطرق Methods ماهي الا اجراءات Sub’s او دوال Function معرفة داخل الفئة، ولا اعتقد انك بحاجة الى اعادة الفصل الثالث "لغة البرمجة BASIC " لتفاصيل بناء الاجراءات والدوال. مع ذلك، هذا مثال لطريقة تابعة للفئة :CPerson

Public Sub SetData(sName As String, dBirthDate As Date, sAddress As Variant)
Me.sName = sName
Me.dBirthDate = dBirthDate
Me.sAddress(0) = sAddress(0)
Me.sAddress(1) = sAddress(1)
Me.sAddress(2) = sAddress(2)
End Sub

بامكانك استدعاء هذه الطريقة بدلا من تعيين كل خاصية على حده:

بدلا من تعيين الخصائص ‘
Turki.sName = txtName.Text
Turki.dBirthDate = CDate ( txtBirthDate.Text )
Turki.sAddress (0) = txtAddress1.Text
Turki.sAddress (1) = txtAddress2.Text
Turki.sAddress (2) = txtAddress3.Text

استدعي الطريقة ‘
Turki.SetData txtName, CDate(txtBirthDate), Array(txtAddress1, _
txtAddress2, txtAddress3)

ملاحظة: حتى لو لم تقتع بفكرة تعيين الخصائص باستخدام الطرق كما في

المثال السابق، تذكر ان استدعاء الطريقة السابقة اسرع بخمس مرات من تعيين قيمة كل خاصية على حده، وستؤثر هذه السرعة كلما كانت اكواد الكائن ابعد –كمكونات COM او .DCOM

بناء الاحداث

عندما نربط بين كلمتي الاحداث والفئات يتبادر لذهن مبرمجي VB4 حدث الانشاء

Class_Initialize والانهاء Class_Terminates . لكن مع الاصدارات الاحدث، اصبحت الفئات قابلة على انشاء وتعريف احداث جديدة قابلة للتصريح من العملاء Clientsالمستخدمين لتلك الفئة –والذين قد تكون انت احدهم.

الفكرة ليست صعبة او مختلفة عن الاحداث الموجودة في الادوات ، لن أخذ مثلا نافذة النموذج Form ، تم تعريف حدث فيها باسم Click ولاشتقاق واستخدام ذلك الحدث كل ما هو مطلوب منك وضع اسم الكائن ثم شرطة سفلية ومن ثم اسم الحدث كما في هذا الكود:

Private Sub Form_Click()
اشتقاق حدث النقر من كائن النموذج ‘
End Sub

من هنا يتضح لنا ان الحدث بكل بساطة عبارة عن اجراء Sub قد يحتوي على

متغيرات اضافية Parameters آالموجودة في حدث MouseDown او .KeyPress

الذي سنفعله هنا بالضبط هو تعريف حدث باسم DataHasBeenSent موجود في الفئة CPerson . ولتعريف هذا الحدث الجديد في الفئة سنستخدم الكلمة المحجوزة :Event

تعريف حدث جديد ‘
Event DataHasBeenSent(objTo As CPerson, bSuccess As Boolean)

لكن مهلا ! متى يستم تنفيذ هذا الحدث؟ هل سيكون ذلك عند استخدام خصائص وطرق الكائن كل مرة؟ ام عندما تزداد شهوة Visual Basic لتفجير الاحداث؟

والجواب في أي وقت تريده عن طر يق استخدام العبارة RaiseEvent في داخل

الفئة. اكتب هذا الكود في الفئة :CPerson

Option Explicit
تعريف حدث جديد ‘
Event DataHasBeenSent(objTo As CPerson, bSuccess As Boolean)
تعريف طريقة جديدة في الفئة ‘
Public Sub SendData(objTo As CPerson)

هنا سنقوم بتفعيل الحدث ‘
If objTo Is Nothing Then
RaiseEvent DataHasBeenSent(objTo, False)
Else
RaiseEvent DataHasBeenSent(objTo, True)
End If
End Sub

والان ننتقل الى الجهة الاخرى ومعرفة كيفية التفاعل مع هذا الحدث كما تتفاعل

مع احداث الادوات الاخرى كـ Click وغيرها ، تتم العملية بنفس الطريقة التي تتعامل مع الادوات شريطة:

  • استخدام الكلمة المحجوزة WithEvents مع تعريف الكائن.
  • لا يكون الكائن تابع لمصفوفة.
  • ان يتم الاعلان عن الكائن على مستوى الوحدة -أي .Public

سننشئ كائن باسم Caller من الفئة CPerson وسنحا ول الاستجابة لاحداث ذلك الكائن، في نافذة النموذج اكتب هذا الكود:

Option Explicit
Dim WithEvents Caller As CPerson
Private Sub Form_Click()
Dim Khaled As CPerson
Set Khaled = New CPerson
”خالد“ = Khaled.sName
Caller.SendData Khaled
End Sub

Private Sub Form_Load()
Set Caller = New MyClass
End Sub

Private Sub Caller_DataHasBeenSent(objTo As CPerson, bSuccess As Boolean)
If bSuccess Then
CPerson.sName "تم ارسال البيانات بنجاح الى: " MsgBox
Else
”لم اتمكن من ارسال البيانات“ MsgBox
End If
End Sub

ملاحظة : لا يوجد داعي لكتابة اسم الحدث الطويل بلوحة المفاتيح، فبمجرد

تعريفك للسطر الذي توجد به كلمة WithEvents انتقل الى القائمة المنسدلة Combo Box في اعلى يسار نافذة التحرير حتى ترى اسم الكائن MyCaller مع باقي اسماء الادوات الموجود ة في النافذة.

مثال مبسط جدا يوضح طريقة الاستجابة للحدث Caller_DataHasBeenSent ، الذي يتم تفجيره بمجرد نجاح الطريقة .SendData

القاء الاحداث:

عن طريقة الكلمة المحجوزة WithEvents تستطيع تطبيق مبدأ القاء الاحداث

Event Multicasting ، وهي عملية رمي الاحداث من كائن او اداة الى فئة كائن

آخر بمجرد تفجير الحدث وقبل ان تنفيذ اكواده . سأوضح الفكرة بالمثال القديم

الموجود في الفصل الثاني "النماذج والادوات " وبالتحديد عند فقرة "السيطرة على المدخلات" التابعة لفقرة "أداة النص TextBox "، تلاحظ ان الكود المستخدم للسيطرة على المدخلات كان طويل جدا، وقد اتفقنا –منذ البداية - انه من غير المعقول استخدام كل هذه الاكواد للتحقق من القيمة التي يكتبها المستخدم في خانة النص، ولكن هنا سنستخدم الكود مرة واحدة فقط، وسنضعه في فئة باسم :CNumTextBox

الاداة التي ستلقي احداثها الينا ‘
Public WithEvents TextControl As TextBox
اكواد تمنع المستخدم من كتابة إلا الارقام ‘
Private OldText As String
Private OldSelStart As Long

Private Sub TextControl_GotFocus()
عندما يكون التركيز على الاداة ‘
لابد من حفظ قيمتها ‘
OldText = TextControl.Text
OldSelStart = TextControl.SelStart
End Sub

Private Sub TextControl_Change()
متغير يمنع استدعاء الاجراء تراجعيا ‘
Static bExitNow As Boolean
If bExitNow Then Exit Sub
If Not IsNumeric(TextControl.Text) Then
المفتاح المدخل ليس رقم ‘
قم باعادة عرض القيمة القديمة ‘
bExitNow = True
TextControl.Text = OldText
bExitNow = False
TextControl.SelStart = OldSelStart
Else
القيمة المدخلة رقمية اذا ‘
قم بحفظها ‘
OldText = TextControl.Text
OldSelStart = TextControl.SelStart
End If
End Sub

Private Sub TextControl_KeyDown(KeyCode As Integer, Shift As Integer)
OldSelStart = TextControl.SelStart
End Sub

Private Sub TextControl_KeyUp(KeyCode As Integer, Shift As Integer)
OldSelStart = TextControl.SelStart
End Sub

Private Sub TextControl_MouseUp(Button As Integer, Shift As Integer, _
X As Single, Y As Single)
OldSelStart = TextControl.SelStart
End Sub

Private Sub TextControl_Click()
OldSelStart = TextControl.SelStart
End Sub

والان في كل مرة تريد انشاء اداة نص TextBox جديدة لا تقبل إلا الاعداد، فلا يوجد داعي لكتابة كل الاكواد السابقة، وانما قم بالقاء جميع احداث اداة النص الى الفئة:

Dim NumText As New CNumTextBox
Dim NumText2 As New CNumTextBox

Private Sub Form_Load()
Text1 = “0”
Text2 = “0”
Set NumText.TextControl = Text1
Set NumText2.TextControl = Text2
End Sub

تمكنا ببساطة شديدة في الكود السابق من جعل الاداتين Text1 و Text2 لا

تقبلان إلا اعداد بفضل القاء الاحداث .Event Multicastin

الى هنا انتهى شرح الأستاذ تركي العسيري بالنسبة لكيفية إنشاء الفئات.

أرجوا ان يكون الكل فهم الدرس وانما كان النقل لتعم الفائدة للجميع.

تم تعديل هذه المشاركة بواسطة كلمة الـعـرب في 20 مايو 2006 في 18:18

((رحلة العودة الى العالم الافتراضي قد بدأت))

#3

موضوع جميل ... تشكر على مجهوداتك اخي الكريم..

وجزاك الله خير.

من سجن عكا وطلعــت جنـازة...

محمد جمجوم و فؤاد حجـازي

جازي عليهم يا شعبــي جازي...المندوب السامي وربعه عموما

محمد جمجوم ومع عطا الزير...فؤاد حجـــــــــازي عز الذخيـره

فلـسطـين

#4

رائع شكرااااااا لك ع الموضوع الشيق

وجزاك الله خير

redahashem

رضا هاشم

اللهم اصلح امورالمسلمين

سبحان الله وبحمده سبحان الله العظيم

اللهم اهلك من سبب في فرقتنا وسفك دمائنا وزاد همنا وكربنا

#5
18_05_06_01_05_06_114798270636_1_11[1].gif

تم تعديل هذه المشاركة بواسطة eng2002 في 21 مايو 2006 في 14:08

استغفر الله العظيم من كل ذنب وأتوب إليه

#6

السلام عليكم

موضوع جميل بالفعل

ساثبت الموضوع لفترة , قبل نقله لقسم الدروس ,,,,

Hany Saad Mostafa

ITI (Information Technology Institute) l

SD Dept.-Teaching Assistant

---

اسألكم الدعاء بظهر الغيب

#7

مشكووووووووورين على مروركم الكريم

شكراَ لك اخي hanysaad على تثبيت الموضوع

((رحلة العودة الى العالم الافتراضي قد بدأت))

#8

مشكور اخي الكريم علي هذه الدروس فكم مرة طالبنا دروس في بناء الفيئات ولم يرد علينا احد

ارجو منك مزيد من الدروس في هذا الموضوع

#9

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

يسلموا ايديك على هذا الموضوع يا اخي فعلا كنت مستني هيك مواضيع

شكوت الى وكيع سوء حفظي فأشار على بترك المعاصي واخبرني ان علم الله نور و نور الله لا يأتي لعاصي

هذا الموضوع مغلق.

مواضيع مشابهة