تقييم الموضوع :
  • 0 أصوات - بمعدل 0
  • 1
  • 2
  • 3
  • 4
  • 5
[سؤال] ما الفرق بين ال Classes و Structures
#1
السلام عليكم ورحمة الله وبركاته
حياكم الله اخوانى الكرام  Smile

أريد معرفة ما هو الفرق بين Class و Struct ؟!

يعنى متى أستخدم هذه ومتى الأخرى وياريت مثال يوضح الفكرة
وجزاكم الله خيرا،،،
الرد }}}}
تم الشكر بواسطة:
#2
عليكم السلام أخي
الاجابة تتلخص كالأتي :
الكلاس من النوع المرجعي والتركيب من النوع القيمي
أي أن الكلاس يتم خزنه في الذاكرة بشكل مؤشرات فقط والتركيب يتم خزن قيمته معه
لذلك تكون الكلاس خفيفة الحمل على الحاسوب ولا تتكرر البيانات المخزونه في الذاكرة لذلك لن يكون هنالك اسراف في استخدام الرام
لكن التركيب Structure وكل الانواع ذوات القيمة الأخرى تعتبر أسرع
لذلك انصحك عندما يكون النوع الذي انت بصدد تصميمه يتم تداوله وتناقله كثيرا في البرنامج ان تستخدم الفئات
وتستخدم التراكيب عندما تكون المعلومات المحفوظة بداخله بسيطة وقيمية غير مرجعية

فهم هذا الفرق الجوهري مهم جدا

يمكنك تصفح الانترنت حول موضوع value type and reference type

كما ان التراكيب لا تمتلك قابلية الوراثة وشكرا
الرد }}}}
تم الشكر بواسطة: LoveVb , نور الدين وليد , Amir_alzubidy , Amir_alzubidy
#3
جزاك الله خيرا . Smile
ولكن لم أفهم متى استخدم هذه ومتى تلك؟
ممكن مثال يوضح الفكرة.
الرد }}}}
تم الشكر بواسطة:
#4
السلام عليكم

نعنم ... كلام  أ الاستاذ صحيح  
Structs are value types
Classes, are reference types




اعطيك مثال :

كود :
  struct TotalCost
       {
           public int ItemsCount, Price;
           public TotalCost(int ItemsCount, int Price)
           {
               this.ItemsCount = ItemsCount;
               this.Price = Price;
           }
       }


تتعامل معاه  :;
كود :
 TotalCost totalCost = new TotalCost(10, 19);

Abu Ehab : Microsoft Partner  & Systems Developer
الرد }}}}
تم الشكر بواسطة: Amir_alzubidy , نور الدين وليد
#5
يمكنك استخدام الفئات دائما فهي تغطي جميع المميزات تقريبا
الرد }}}}
تم الشكر بواسطة: WAEL ABED , WAEL ABED
#6
متى تستخدم الـ Sturct

بالنسبة لي اعتبر الـ Struct مجرد حاوية لبعض القيم من صنف واحد ، لا اكثر



مثال 1 :

نعرف ان الفضاء الثلاثي الابعاد لديه 3 محاور :

اذن لو اردنا وصف نقطة في هذا المجال في برنامجنا وعرضها على الشاشة مقلا ، نستطيع عمل 3 متغيرات عادية بهذا الشكل :

PHP كود :
           int x 2;
 
           int y 3;
 
           int z 4;

 
           MessageBox.Show(x.ToString() + y.ToString() + z.ToString()); 
لكن بالطبع هذه الطريقة تافهة جدا لتوصيف النقاط ، حيث انك ستعرف 3 متغيرات لكل نقطة !!! شيئ متعب جدا
قد يقول البعض سأستعمل المصفوفات ، ولكن المصفوفات مجرد حل فاشل هو الاخر لانها لم تخصص للتعامل مع هذا الاسلوب.
الحل المثالي ، استعمال انشاء struct :

PHP كود :
       struct Vector3D
        
{
 
           public int xyz;

 
           public Vector3D(int xint yint z)
 
           {
 
               this.x;
 
               this.y;
 
               this.z;
 
           }
 
       


الان يمكننا وصف النقطة وعرضها بدون عمل متغيرات :
PHP كود :
           Vector3D vector = new Vector3D(234);

MessageBox.Show(vector.x.ToString() + vector.y.ToString() + vector.z.ToString()); 


اذن كما تلاحظ جمعنا قيم من نفس الصنف في Type واحد وهذه فائدة عظيمة ، هل هذا كل شيئ ؟؟؟؟ لا ...

انظر لهذا السطر كم هو قبيح :
PHP كود :
MessageBox.Show(vector.x.ToString() + vector.y.ToString() + vector.z.ToString()); 


هل يمكننا عمل امر بخصوص هذا الموضوع ، نعم يمكنك عمل override للدالة ToString وتجعلها كالتالي مثلا :-

PHP كود :
       struct Vector3D
        
{
 
           public int xyz;

 
           public Vector3D(int xint yint z)
 
           {
 
               this.x;
 
               this.y;
 
               this.z;
 
           }

 
           public override string ToString()
 
           {
 
               return "x:" " y:" " z:" z;
 
           }
 
       


الان عند العرض :-

PHP كود :
           Vector3D vector = new Vector3D(234);

 
           MessageBox.Show(vector.ToString()); //x:2 y:3 z:4 


كم هذا مريح ، وهل هذا كل شيئ ، لاااا Big Grin  تستطيع اضافة عمليات تختص بالVector داخل الstruct
مثلا عملية جمع كائنين من 2 vectors
PHP كود :
       struct Vector3D
        
{
 
           public int xyz;

 
           public Vector3D(int xint yint z)
 
           {
 
               this.x;
 
               this.y;
 
               this.z;
 
           }

 
           public override string ToString()
 
           {
 
               return "x:" " y:" " z:" z;
 
           }

 
           public static Vector3D operator+ (Vector3D a Vector3D b)
 
           {
 
               return new Vector3D(a.b.xa.b.ya.b.z);
 
           }
 
       





يمكننا ايضا اضافة احدى العمليات الحسابية التي تتعلق بالVectors مثلا حساب الـ Magnitude :

PHP كود :
           public static Vector3D operator+ (Vector3D a Vector3D b)
 
           {
 
               return new Vector3D(a.b.xa.b.ya.b.z);
 
           }

 
           public double Magnitude
            
{
 
               get { return Math.Sqrt(Math.Pow(x2) + Math.Pow(y2) + Math.Pow(z2));  }
 
           



وفي النهاية :
PHP كود :
           Vector3D vector = new Vector3D(234);
 
           Vector3D vector2 = new Vector3D(33213);

 
           Vector3D finalVector vector vector2//جمع الفيكتور
 
        
            MessageBox
.Show(finalVector.Magnitude.ToString()); //عرض الماغنيود 




----





مثل ماتلاحظ قمنا بعمل Type احترافي للـ Vector من الـ Struct


طبعا هذا لايعني انه لايمكننا عمله باستعمال الـ Class ولكن الطريقة الامثل اكيد باستعمال الـ Struct

اساسا لو استعملنا الـ Class بتواجهنا الطامة الكبرى بخصوص عملية الـ Assignment وذلك بسبب ان الـ Class هو Reference Type
هل تريد ان تعرف المشكلة التي ستحصل لو استعملنا الـ Class ؟؟؟

بافتراض حولنا الstruct الذي انشاناه الى class :

PHP كود :
       class Vector3D
        




ثم حاولنا كتابة التالي :


PHP كود :
           Vector3D vector = new Vector3D(234);


 
           Vector3D vector2 vector;
 
       
            vector
.120200;
 
           vector.323232;
 
           vector.343511;


 
           MessageBox.Show(vector2.ToString()); //120200 , 323232, 343511
 
           MessageBox.Show(vector.ToString()); //120200 , 323232, 343511 


الرسالتين اعلاه سيطبعان نفس النتيجة !!!!!!!!!!!!!!!!!!!!

يالها من فاجعة .... كيف ذلك !!
فكما نلاحظ لم يتم العبث في قيمة الكائن vector2 ، بل تم التعديل على الكائن vector
اذن مادخل الكائن المسكين vector2 في الموضوع . هل فقط لانه استعار القيمة الابتداية من الكائن vector  !!! ياللظلم  Big Grin


نعم هذه طبيعة عمل الClass ، فهو كالـ Pointers ..
مما يعني انه اي تعديل على احد الكائئنات التي تم عمل Assignment لها ، راح يغير على الكائنات الاخرى .  Dodgy



فالان لو فقط  ارجعنا الـ class الى struct
PHP كود :
       struct Vector3D
        




لن تكون هناك المشكلة التي ناقشناها بالاعلى ، فكل كائن يشير الى نفسه Smile

PHP كود :
           Vector3D vector = new Vector3D(234);
 
           Vector3D vector2 vector;

 
           vector.10;
 
           vector.30;
 
           vector.50;

 
           MessageBox.Show(vector.ToString()); //10 , 30, 50
 
           MessageBox.Show(vector2.ToString()); //2 , 3, 4 


هذا هو الفرق التقني الكبير بين الـ Struct وبين الـ Class



--




وكما قلت سابقا ، نستعمل الـ Sturct عندما تكون لدينا عدة قيم بسيطة من نفس الصنف
مثلا الـ Time يحتوي على ساعة ودقائق وثواني ، لذلك نعرفه Struct
مثلا الـ Size يحتوي على محور سيني ومحور صادي ، لذلك نعرفه Struct
مثلا الـ Address يحتوي على عدة ارقام او نصوص، لذلك نعرفه Struct
مثلا الـ Range يحتوي على رقم بداية ونهاية، لذلك نعرفه[b]Struct[/b]
مثلا المستطيل (Rectangle) يحتوي على 4 قيم من نفس النوع ، يمكننا تعريفه كـ Struct

وفي نفس الوقت يمكننا تعريف الـ Rectangle مثلا كـ Class في حالة كان الاستخدام معقدا


مثلا لو عرفنا الـ Rectangle كـ Struct ثم اضفنا فيه اكواد لعمليات الرسم بالGDI والطباعة وغيرها من الامور التي تتعامل مع Unmanaged Resources
اعتقد تصبح مشكلة وقد يحصل كراش ايضا ، لذلك اي Type تريد استخدامه كـ (سلاح ثقيل)  استعمل الـ Class
اما (الاسلحة الخفيفة) مثل العمليات الحسابية والتحويلات وغيره استعمل الـ Struct


واهم شيئ ، لاتنسى موضوع الـ Value Type الذي وضحته بالاعلى




تحياتي
الرد }}}}
تم الشكر بواسطة: Fantastico , نور الدين وليد
#7
اخي الفاضل الشاكي لله

كلامك جيد جدا .............
لكن فعليا لايوجد فارق كبير بين Structure و Class إلا في الأفضلية للإستخدام مع ٌValueType و Ref Type
وأكاد اجزم انه لا يوجد فارق علي الإطلاق

الأمر كله مرتبط بأسلوب كتابة الكود الخاص بأي Structure

و اسمح لي أن اقبتس من كلامك الأتي تحديدا

إقتباس :يالها من فاجعة .... كيف ذلك !!
فكما نلاحظ لم يتم العبث في قيمة الكائن vector2 ، بل تم التعديل على الكائن vector
اذن مادخل الكائن المسكين vector2 في الموضوع . هل فقط لانه استعار القيمة الابتداية من الكائن vector  !!! ياللظلم

اعتقد ان اسلوب كتابة Structure الخاص بك هو ما يؤثر في عملية Clone

حاول تعيد كتابة Structure بهذا الشكل

PHP كود :
Public Structure Vector3D
    Implements ICloneable

    Public Property X 
As Integer
    Public Property Y 
As Integer

    Public Property Z 
As Integer

    Public 
Function Clone() As Object Implements ICloneable.Clone
 
       Return Me.CreateDeepCopy(CreateShallowCopy())
 
   End Function

 
   Friend Function CreateShallowCopy() As Vector3D
        Return CType
(New Vector3D With {.0, .0, .0}, Vector3D)
 
   End Function
 
   Friend Function CreateDeepCopy(current As Vector3D) As Vector3D
        Return current
    End 
Function

End Structure 


ثم حاول صياغة الكود الخاص بك مرة اخري ليكون هكذا


PHP كود :
      Dim v As Vector3D = New Vector3D With {.100, .200, .300}
 
       Dim v1 As Vector3D v
        v1
.10
        v1
.20

        
' هذا السطر من الكود الهدف منه عرض النتائج فقط
        Me.Text = v1.X & "," & v1.Y & "," & v1.Z 

تقبل تحياتي و عذرا لكتابة الكود بلغة VB.net
الرد }}}}
تم الشكر بواسطة: الشاكي لله , نور الدين وليد
#8
جزاك الله خيرا أستاذ الشاكي لله 
شرحك كان أكثر من رائع...  Smile

ولكن الاستاذ Silverlight لم أفهم قصدك  Huh

(20-09-16, 01:03 PM)Fantastico كتب :   لذلك تكون الكلاس خفيفة الحمل على الحاسوب ولا تتكرر البيانات المخزونه في الذاكرة لذلك لن يكون هنالك اسراف في استخدام الرام
  لكن التركيب Structure وكل الانواع ذوات القيمة الأخرى تعتبر أسرع
كيف الكلاس خفيفة واخف من التركيب على الذاكرة وفى نفس الوقت التركيب اسرع Huh
الرد }}}}
تم الشكر بواسطة:
#9
(22-09-16, 05:38 PM)silverlight كتب : اخي الفاضل الشاكي لله

كلامك جيد جدا .............
لكن فعليا لايوجد فارق كبير بين Structure و Class إلا في الأفضلية للإستخدام مع ٌValueType و Ref Type
وأكاد اجزم انه لا يوجد فارق علي الإطلاق


اهلا بك اخي سيلفرلايت (ارجو ان اتعرف على اسمك) Smile


يبدو انك تسرعت اخي العزيز لان ببصراحة اختلف معك جدا ، هناك عدة اختلافات او بالاحرى (limits) لاستخدام الـ Struct

بعيدا عن موضوع الـ Ref & Value Type ، هناك عدة اختلافات من ناحية مبادئ الـ OOP

1- عدم قدرة الـ Struct من الوراثة من الـ Types الاخرى (ماعدا الـ Interface)
2- عدم قدرة الـ Struct على انشاء Contractor بدون بارمترات
3- عند تعريف متغيرات او خصائص عامة في الـ Struct ـ يجب عليك ملأها من الـ Contractor ولايمكنك اسناد قيمة افتراضية لهم مباشرة
4- عدم تقبل كائن الـ Struct الى القيمة null او nothing (فيجوال بيسك)


هذه الفروق وحدها تجعل الفارق ليس بالصغير بين الـ Class والـ Struct
الرد }}}}
تم الشكر بواسطة: نور الدين وليد
#10
أخي الفاضل الشاكي لله

اولا : أعلم جيدا الفارق بين Structure و Class و أفهم فكرة التوريث جيدا Smile
لكن ...........................
مثلا الغالبية تقول ان Structure يتم استخدامه مع ValueTypes
لذلك ارجو منك ان تلقي نظرة علي الكود التالي
فهو يغير قليلا من المفاهيم الخاصة بكل من Structure و Class

و عفوا مرة ثانية لإستخدامي لغة الفيجوال بيسك دوت نت بدلا من #C

PHP كود :
Public Structure CairoString

    Private _value 
As String

    Public Sub 
New(value As String)
 
       Me._value value
    End Sub

    Private Shared 
empty As CairoString = New CairoString(String.Empty)

 
   Public Shared ReadOnly Property IsEmpty() As CairoString
        Get
            Return 
empty
 
       End Get
    End Property

    Public Property Text
() As String
        Get
            Return _value
        End Get
        Set
(value As String)
 
           _value value
        End Set
    End Property

    Public Shared 
Function IsNullOrEmpty(cs As CairoString) As Boolean
        Return cs
.Text Is Nothing OrElse String.IsNullOrEmpty(cs.Text)
 
   End Function

 
   Public Shared Widening Operator CType(cs As CairoString) As String
        If cs
.Text IsNot Nothing Then
            Return cs
.Text
        End 
If
 
       Return Nothing
    End Operator

    Public Overrides 
Function Equals(obj As Object) As Boolean
        Dim s 
As String TryCast(objString)
 
       If s IsNot Nothing Then
            Return s
.Equals(Me.Text)
 
       End If
 
       Dim cs As CairoString CType(objCairoString)
 
       Return cs.Text IsNot Nothing AndAlso cs.Text.Equals(Me.Text)
 
   End Function

 
   Public Overrides Function GetHashCode() As Integer
        If Me
.Text IsNot Nothing Then
            Return Me
.Text.GetHashCode()
 
       End If
 
       Return 0
    End 
Function

 
   Public Overrides Function ToString() As String
        Return Me
.Text
    End 
Function

End Structure 

الإستخدام ........

PHP كود :
       Dim cs As New CairoString("VB4Arab")
 
       Me.Text cs.Text


        Dim cs1 
As CairoString cs
        cs1
.Text "any String"
 
       Me.Text cs1.Equals(cs


ما أريد ان أقوله أنه تقريبا لا يوجد فارق كبير بين كل من Structure و Class
الأمر فقط متروك للمبرمج الذي يكتب الكود
و في الكيفية التي سيستخدمها المبرمج لكتابة الكود و كتابة البيانات في كل من Structure و Class

و أخيرا هذا اثبات بسيط أن مايكروسوفت أحيانا ب تقول اي كلام في اي كلام
أليك هذه المعادلة العجيبة ........... او كما نقول في مصر إليك هذه الفزورة
String أصله Char و ........ Char أصله Structure Wink


تقبل تحياتي ................ بالمناسبة اسمي : مهندس عمر Smile
الرد }}}}
تم الشكر بواسطة: نور الدين وليد


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


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