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

العموميات في جافا Generics

مغلق
بدأه nardien28 في 6 أغسطس 2006 · 28 رد · 10,439 مشاهدة · في JavaSE
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

امتدادات للغة البرمجة جافا تمت اضافتها في JDK 1.5 اضافت خاصية امكانية اضافة مفهوم التجريد على الانماط

مثال الأنماط الحاوية مثل المجموعات وتصنيفاتها

List myIntList = new LinkedList(); 
myIntList.add(new Integer(0)); 
Integer x = (Integer) myIntList.iterator().next();

نلاحظ في السطر الثالث التحويل القسري

عادة يعلم المبرمج نوع البيانات التي سيتم وضعها في اللائحة لذلك فإن التحويل القسري مهم

ولكن كل ما يعرفه المترجم ان ال iteratorسيعيد يرجع غرض من نمط Object

التحويل القسري مهم لضمان عملية ربط المتحول بالنمط Integer تنميطا امنا

لكن التحويل القسري يؤدي الى نوع من الفوضى والبلبلة حيث انه من المحتمل ان يؤدي الى اخطاء في زمن التنفيذ بسبب خطأ من المبرمج .

ماذا اذا استطاع المبرمجون التعبير عن توجيه اللائحة بأن تحوي نوع محدد من البيانات

هذه هي الفكرة الأساسية من العموميات

List<Integer> myIntList = new LinkedList<Integer>(); 
myIntList.add(new Integer(0));
Integer x = myIntList.iterator().next();

بملاحظة عملية التصريح عن المتحول myIntList

نجد ان هناك عملية تحديد اجباري للائحة انها لائحة بيانات من نوع Integer

بكتابة List<Integer> نقول ان List هي واجهه عمومية تأخذ (يتم تمرير) وسيط هو نمط ما في هذه الحاله هو Integer

قمنا ايضا بتحديد نمط البارامتر عند عمل الغرض list

يجب ملاحظة اننا بما فعلناه قمنا بالاستغناء عن عملية التحويل القسري في السطر الثالث

فبدلا عن عملية القسر الى Integer قمنا بجعل Integer كنمط تمرير في السطر الأول

قد تبدو الخطوة بسيطة لكن في الحقيقة حصل اختلاف كبير

اصبح بإمكان المترجم الأن ان يراقب صحة التنميط في زمن الترجمة

عندما نشير ان الائحة myIntListمصرح عنها بالنمط List<Integer> هذا يؤكد ان المتحول myIntList سيحمل قيم صحيحة أينما ووقتما يتم استخدامه والمترجم سيضمن هذا

بينما عند استخدام التحويل القسري سنقرأ بما يظنه المبرمج صحيحا

هذا يزيد القروءية الكود ومتانته خاصة في البرامج الضخمة

تم تعديل هذه المشاركة بواسطة مجدي محمود في 16 أغسطس 2006 في 17:47

سيمضي ركبنا العملاق لن يركع .. بإيمان لغير الحق لا يصدع

عزيزا شامخا كالمجد بل أروع .. فسجل أيها التاريخ ما تسمع :

فلسطين لنا الآمال والمطمع .. نعاهد أن نحررها وأن ترجع

ونقسم نستعيد الأرض أو نصرع .. ويبقى رمزنا الزيتون والمدفع

Palestine.gif

#2

تعريف عموميات بسيطة

تعريف كل من الواجهه List و Iterator كما وردت في الحزمة java.util

public interface List<E> { 
void add(E x);
Iterator<E> iterator();
}

public interface Iterator<E> { 
E next();
boolean hasNext();
}

تبدو مألوفة باستثناء القوسين المثلثين <> حيث هذه هي التعريفات للوسيط النمط الشكلي أو (بارامترات النمط )

ممكن استخدامها في التصريح العام

في عملية الاستدعاء يتم تبديل وسيط النمط الشكلي( في مثالنا E ) بالوسيط النمط الحقيقي ( في المثال Integer)

public interface IntegerList { void add(Integer x)
Iterator<Integer> iterator();
}

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

تصريح النمط العمومي يتم ترجمته مره واحده لأجل كل شيء ويتم تحويله الى ملف صف واحد منفصل مثل اي صف اعتيادي

البارامتر (الوسيط) يشبه البارامترات الاعتيادية المستخدمة في الطرائق او البواني

ذلك اشبه ببرامتر القيمة الشكلية لطريقة ما التي تصف نوع القيم التي سيتم تمريرها

كذلك التصريح العمومي لديه بارامترات نمط شكلي

عند استدعاء الطريقة (الاجرائية) يتم تعويض البارامتر الحقيقي مكان البارامتر الشكلي ويتم الحصول على جسم الإجرائية المطلوب.

على شاكله عند استدعاء التعريف العمومي يتم التعويض ببرامتر النمط الحقيقي مكان البارامتر النمط الشكلي .

سيمضي ركبنا العملاق لن يركع .. بإيمان لغير الحق لا يصدع

عزيزا شامخا كالمجد بل أروع .. فسجل أيها التاريخ ما تسمع :

فلسطين لنا الآمال والمطمع .. نعاهد أن نحررها وأن ترجع

ونقسم نستعيد الأرض أو نصرع .. ويبقى رمزنا الزيتون والمدفع

Palestine.gif

#3

بارك الله فيك

وزادك الله علما ان شاء الله

سبحانك اللهم وبحمدك أشهد ان لا اله الا أنت

أستغفرك وأتوب اليك

الهم صلي وسلم وبارك على سيدنا وحبيبنا محمد

#4

العموميات والتنميط الجزئي

لنحاول اختبار فهمنا للعموميات .. هل تظن ان الكود التالي نظامي ؟

List<String> ls = new ArrayList<String>();		//1
List<Object> lo = ls;										  //2

السطر الأول نظامي بينما السطر الثاني يقودنا الى سؤال هل لائحة من String هي نفسها لائحة من Object ؟؟ ..

الجميع سيجيب ب " نعم " نسبة الى ظاهرة الترادف في جافا

بملاحظة الكود التالي

lo.add(new Object());  // 3
String s = ls.get(0);	 // 4:   attempts to assign an Object to a String!

لدينا اللائحتان ls و lo بالوصول الى اللائحة ls ( لائحة ال String ) عبر اللائحة lo ( لائحة ال Object)فإننا سنستطيع ادخال أي عنصر Object فيها

والنتيجة ان اللائحة ls لن تحمل عناصر من نمط String فقط وعند محاولة ادخال او الحصول على عناصر من انماط عدا String

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

مثال لذيذ بالفواااااااااااااااااااكه

بفرض اني أملك سلة (لائحة list) للفواكه ( صف فاكهه ) بالتالي بإمكاني اضافة برتقال , تفاح , موز (صفوف ترث الصف فاكهه) .. أي من أنواع الفواكه .

ماذا لو أنشأت سلة موز (لائحة ذات برامتر الصف موز ) من المفترض أن لا اضيف اليها الا الموز ويجب منع اضافة أي نوع اخر من الفوكه .

مممم ... هل نستطيع اعتبار سلة الموز ترث سلة الفواكه ؟

57092b5480.gif

لو كان هذا صحيحا لحصلنا على مرجع reference من النمط سلة فواكه للإشارة على مثيل instance من سلة الموز .

عندئذ يمكن اضافة الموز الى السلة ولكن هذا يسمح بإضافة البرتقال الى السلة وهذا ما لا نريده .

يمكن استخدام سلة الفواكه كسلة موز ولكن لا يمكن استخدام سلة الموز كسلة فواكه .

لن يتم تعويض سلة موز مكان سلة فواكه تحت أي ظرف من الضروف وإلا سنحصل على استثناء زمن التنفيذ

Error: line (9) incompatible types found :
سلة موز
required: سلة فواكه

سيمضي ركبنا العملاق لن يركع .. بإيمان لغير الحق لا يصدع

عزيزا شامخا كالمجد بل أروع .. فسجل أيها التاريخ ما تسمع :

فلسطين لنا الآمال والمطمع .. نعاهد أن نحررها وأن ترجع

ونقسم نستعيد الأرض أو نصرع .. ويبقى رمزنا الزيتون والمدفع

Palestine.gif

#5

الرموز العامة Wildcards

تخيل مشكلة كتابة كود برمجي لطباعة كل العناصر في مجموعة ما collection

قد تكتب هذا الكود في احدى النسخ الأقدم من جافا

void printCollection(Collection c) { 
Iterator i = c.iterator();
for (k = 0; k < c.size(); k++) { System.out.println(i.next());}
}

وهنا محاولة لحل المشكلة باستخدام العموميات

void printCollection(Collection<Object> c) { 
for (Object e : c) { System.out.println(e);}
}

المشكلة ان المحاولة الثانية اقل جدوى وفائدة من الأولى

الكود الأول يمكن استدعاءه مع اي نوع من المجموعات كبارامتر بينما الكود الثاني لا يقبل الا< Collection<Object الذي (كما وضحنا سابقا ) ليس نمط أب لأي نوع من المجموعات .

اذن ما هو النمط الأب لكل المجموعات ؟

الاجابة هي <?>Collection التي تعني مجموعة من غير معروفأو بالأحرى مجموعة عناصرها قد تكون عناصرها من اي نمط

نسميه نمط الرمز العامWildcard

والان نستطيع ان نكتب

void printCollection(Collection<?> c) { 
for (Object e : c) { System.out.println(e);}
}

هذه الاجرائية نستطيع استدعاءها مع اي نمط من المجموعات .

نلاحظ انه ما زال بإمكاننا قراءة العناصر من c واعطائهم النمط Object

هذه ا لطريقة اكثر امانا طالما ان النمط الفعلي للمجموعة يحتوي أغراضا .

ولكنه ليس امنا عملية اضافة اغراض ل c حيث :

Collection<?> c = new ArrayList<String>();
c.add(new Object()); // compile time error

حيث اننا لا نعلم نمط عناصر c وبذلك لا نستطيع اضافة عناصر لها

الطريقة()add تأخذ وسيط من نمط E (نمط عناصر المجموعة)

عندما يكون بارامتر النمط الفعلي هو ؟ هذا يدل على نمط غير معروف وبالتالي اي نمط يتم تمريره الى الطريقة add سيكون نمط جزئي من هذا النمط الغير معروف

طالما نحن لا نعلم ما هو النمط فإننا لا نستطيع تمرير اي شيء اليها باستثناء الحالة null لأنها فرد من كل نمط .

بالمقابل بالكتابة <?>List نستطيع استدعاء() get والاستفادة من النتائج .

النمط الناتج هو نمط غير معرف ولكننا نعلم دوما انه غرض ما object

لذلك فإنه من الأأمن دوما اسناد نتيجة()get الى متحول من النمط Object أو تمريره كبارامتر حيث يكون النمط Object متوقعا

سيمضي ركبنا العملاق لن يركع .. بإيمان لغير الحق لا يصدع

عزيزا شامخا كالمجد بل أروع .. فسجل أيها التاريخ ما تسمع :

فلسطين لنا الآمال والمطمع .. نعاهد أن نحررها وأن ترجع

ونقسم نستعيد الأرض أو نصرع .. ويبقى رمزنا الزيتون والمدفع

Palestine.gif

#6

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

بس يا ريت يا أختي أنك لما تكتبي مصطلحات

مثل العموميات والتحويل القسري يكون الها ترجمة إنجليزية على الأقل في المرة الأولى من ذكرها

لأن هذا يفيد في التتابع الفكري عند محاولة التوسع في الموضوع عدا عن ذلك موضوعك رهيب جداً

وأتمنى على المشرفين تثبيته

اللهم انفعنا بما علمتنا وعلمنا ما ينفعنا

حزمة المحرك الإصدارة 0.8

أي أحد يجد أني ظلمته فليراسلني

وبإذن الله لو كان له حق سيأخذه

728x90.png

#7

معك حق يا اخي ..

العموميات generics

التحويل القسري casting

اللائحة List

نمط type

التنميط الجزئي Subtyping

برامتر النمط الشكلي formal type parameters

واجهه Interface

برامتر القيمة الشكلية formal value parameters

ظاهرة الترادف aliasing

الأنماط الحاوية container types

طرائق methods

سيمضي ركبنا العملاق لن يركع .. بإيمان لغير الحق لا يصدع

عزيزا شامخا كالمجد بل أروع .. فسجل أيها التاريخ ما تسمع :

فلسطين لنا الآمال والمطمع .. نعاهد أن نحررها وأن ترجع

ونقسم نستعيد الأرض أو نصرع .. ويبقى رمزنا الزيتون والمدفع

Palestine.gif

#8

موضوع جميل واتمنى الاستمرار في الشرح سيتم التثبيت

اقتباس
التحويل القسري
اول مرة بعرف انه هذه الكلمة تعني casting :D

لست متواجد بشكل يومي

#9

الرموز العامّة المحدودة Bounded Wildcards

سـأورد مثال بسيط هو تطبيق رسومي بسيط لرسم الأشكال كالمستطيلات والدوائر

لتمثيل هذه الأشكال خلال البرنامج علينا تعريف هرمية للصفوف كالتالي :

public abstract class Shape { 
public abstract void draw(Canvas c);
}
**************************************************
public class Circle extends Shape { 
private int x, y, radius;
public void draw(Canvas c) { ... }
}
**************************************************
public class Rectangle extends Shape { 
private int x, y, width, height;
public void draw(Canvas c) { ... }
}
**************************************************
These classes can be drawn on a canvas:
public class Canvas { 
public void draw(Shape s) { s.draw(this);}
}

أي رسم سيتضمن عددا من الأشكال .

بفرض انه تم التعبير عن هذه الأشكال بلائحة فسيكون من السهل تعريف تابع في صف Canvas الذي سيقوم برسم مجموعة هذه الأشكال

public void drawAll(List<Shape> shapes) { 
for (Shape s: shapes) { s.draw(this);}
}

قاعدة التنميط تنص ان()drawAll تستدعى بوسيط من نمط لوائح من النمط Shape حصرا .

حيث على سبيل المثال لا يمكن استدعاءها على < List<Circle

ما نريده بالضبط هو طريقة (تابع) يقبل لائحة من أي نوع من الأشكال

public void drawAll(List<? extends Shape> shapes) { ... }

هناك اختلاف صغير ومهم هنا اننا قمنا باستبدال النمط < List<Shape بالنمط <List<? extends Shape

الأن ()drawAll ستقبل لوائح من اي صف جزئي ( يرث) الصف Shape

لذلك صار بإمكاننا استدعائها على< List<Circle ان اردنا ذلك

<List<? extends Shape هي مثال على الرموز العامة المحدودة

حيث ان الرمز ؟ يشسر الى نمط غير معروف كما ذكرنا سابقا

ولكننا في هذه الحالة نعلم انه نمط غير معرف بالإضافة الى علمنا انه نمط جزئي من Shape

فنقول ان ان Shape هو حد أعلى للرمز العام .

لكن الثمن الذي ندفعه لقاء المرونه التي تمنح لنا لقاء استخدام الرموز العامة هو انه أصبح من غير المسموح كتابة اجسام الطرق في shapes

مثال توضيحي (الكود التالي غير مسموح)

public void addRectangle(List<? extends Shape> shapes) { 
shapes.add(0, new Rectangle()); // compile-time error!
}

ان نمط البارامتر الثاني للتابع()shapes.add هو ? extends Shape أي نمط غير معرف جزئي من Shape .

طالما اننا لا نعلم ما هو النمط بالضبط وبالتالي نحن لا نعلم ان كان نمط اب للصف Rectangle حيث انه قد يكون وقد لا يكون نمط اب وبالتالي ليس مناسبا تمرير Rectangle هنا .

تم تعديل هذه المشاركة بواسطة nardien28 في 8 أغسطس 2006 في 02:30

سيمضي ركبنا العملاق لن يركع .. بإيمان لغير الحق لا يصدع

عزيزا شامخا كالمجد بل أروع .. فسجل أيها التاريخ ما تسمع :

فلسطين لنا الآمال والمطمع .. نعاهد أن نحررها وأن ترجع

ونقسم نستعيد الأرض أو نصرع .. ويبقى رمزنا الزيتون والمدفع

Palestine.gif

#10

في حد فاهم ؟!!!

سيمضي ركبنا العملاق لن يركع .. بإيمان لغير الحق لا يصدع

عزيزا شامخا كالمجد بل أروع .. فسجل أيها التاريخ ما تسمع :

فلسطين لنا الآمال والمطمع .. نعاهد أن نحررها وأن ترجع

ونقسم نستعيد الأرض أو نصرع .. ويبقى رمزنا الزيتون والمدفع

Palestine.gif

#11

الطرائق العمومية Generic Metods

تخيل كتابة طريقة metod تأخذ مصفوفة أغراض ومجموعة وتضع كل الأغراض الموجودة في المصفوفة في المجموعة

static void fromArrayToCollection(Object[] a, Collection<?> c) { 
for (Object o : a) { 
c.add(o); // compile time error
}}

تعلمنا الابتعاد عن خطأ محاولة استخدام < Collection<Object كنمط لبارامتر مجموعة كما ان استخدام Collection<?> لن يجدي نفعا أيضا .

تذكر بأنك لا تستطيع حشر الأغراض في مجموعة ذات عناصر من نمط غير معرف .

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

كما في التصريحات عن النمط generic types ، التصريح عن الطرق generic metods ممكن ان يكون عمومي ذلك يعني ذو نمط واحد او اكثر من بارامترات الانماط

static <T> void fromArrayToCollection(T[] a, Collection<T> c) { 
for (T o : a) { 
c.add(o); // correct
}}

نستطيع استدعاء هذه الطرق مع اي نوع من المجموعات ذات العناصر التي من نمط أب من نمط عناصر المصفوفة .

Object[] oa = new Object[100];
Collection<Object> co = new ArrayList<Object>();
fromArrayToCollection(oa, co);// T inferred to be Object

String[] sa = new String[100];
Collection<String> cs = new ArrayList<String>();

fromArrayToCollection(sa, cs);// T inferred to be String
fromArrayToCollection(sa, co);// T inferred to be Object

Integer[] ia = new Integer[100];
Float[] fa = new Float[100];
Number[] na = new Number[100];

Collection<Number> cn = new ArrayList<Number>();
fromArrayToCollection(ia, cn);// T inferred to be Number
fromArrayToCollection(fa, cn);// T inferred to be Number
fromArrayToCollection(na, cn);// T inferred to be Number
fromArrayToCollection(na, co);// T inferred to be Object
fromArrayToCollection(na, cs);// compile-time error

لاحظ اننا لسنا بحاجة الى تمرير نمط فعلي كوسيط لطريقة عمومية .

يستنتج المترجم ان نمط الوسيط يعتمد على أنماط الوسطاء الفعلية .

سوف يستنتج بشكل عام الوسيط النمط الأكثر تحديدا الذي سيجعل النمط المستدعى صحيحا .

والسؤال الأن متى يستوجب استخدام الطرق العمومية ؟ ومتى يستوجب استخدام أنماط الرموز العامة ؟

لفهم الاجابات لننظر الى بعض الطرق المعرفة في مكتبات Collection

interface Collection<E> { 
public boolean containsAll(Collection<?> c);
public boolean addAll(Collection<? extends E> c);
}
**************************************************
We could have used generic methods here instead:
interface Collection<E> { 
public <T> boolean containsAll(Collection<T> c);
public <T extends E> boolean addAll(Collection<T> c);
// hey, type variables can have bounds too!
}

في كلا الطريقتان addAll و containsAll فإن بارامتر النمط T تم استخدامه مره واحدة فقط .

نمط الإرجاع لا يعتمد على بارامتر النمط ولا على اي وسيط للطريقة .

هذا يبين لنا انه تم توظيف وسيط النمط لأجل تعددية الأشكال Polyomorphism.

تأثيره الوحيد هو السماح باستخدام لعدد من وسطاء الأنماط الفعلية في حالات الاستدعاءات المختلفة .

قد يخطر بالبال استخدام الرموز العامة .

ان الرموز العامة مصممة بالأساس لدعم مرونة التنميط الجزئي .

الطرق العمومية تسمح لبارامتر النمط ان يتم استخدامه للتعبير عن التبعية بين أنماط لوسيط او للطريقة و نمط الإرجاع .

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

It is possible to use both generic methods and wildcards in tandem. 
Here is the method Collections.copy():
**************************************************
class Collections { 
public static <T> void copy(List<T> dest, List<? extends T> src){...}
}

بملاحظة التبعية بين أنماط كل من البارامترين .

فإن اي غرض يتم نسخه من اللئحة المصدر src يجب ان يكون مسند الى نمط العناصر T للائحة الهدف dst

لذلك فإن نمط العناصر ل src ممكن ان يكون اي نمط جزئي من T .

ان ترويسة الطريقة copy تعبر عن التبعية باستخدام بارامتر نمط ولكن تستخدم رمز عام لنمط العناصر للبارامتر الثاني .

قد نكتب ترويسة هذه الاجرائية بطريقة اخرى بدون استخدام الرمز العام :

class Collections { 
public static <T, S extends T>void copy(List<T> dest, List<S> src){...}
}

بينما بارامتر النمط الأول يتم استخدامه لأجل نمط dst وكحد لبارامتر النمط الثاني S

يتم استخدام S كنمط ل src فقط ولا شيء اخر يعتمد عليه (تابع له)

وهذه هي الاشارة التي تقودنا الى استبدال S برمز عام ان استخدام الرموز العامة أوضح واسهل من التعريف الصريح لبارامتر النمط لذلك علينا تفضيل استخدامه متى كان ممكنا استخدامه .

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

بالعودة لمثال مشكلة رسم الأشكال بفرض اننا نريد حفظ تسلسل طلبات الرسم السابقة .

نستطيع حفظ عمليات الرسم السابقة عبر متحول ساكن في الصف Shape وجعل drawAll() تخزن وسطاء الدخل في الحقل history كالتالي :

static List<List<? extends Shape>> history =new ArrayList<List<? extends Shape>>();
public void drawAll(List<? extends Shape> shapes) { 
history.addLast(shapes);
for (Shape s: shapes) { 
s.draw(this);
}
}

سيمضي ركبنا العملاق لن يركع .. بإيمان لغير الحق لا يصدع

عزيزا شامخا كالمجد بل أروع .. فسجل أيها التاريخ ما تسمع :

فلسطين لنا الآمال والمطمع .. نعاهد أن نحررها وأن ترجع

ونقسم نستعيد الأرض أو نصرع .. ويبقى رمزنا الزيتون والمدفع

Palestine.gif

#12

من وجهة نظر هندسة البرمجيات

الصفوف ذات الوسطاء (البارامترات) Parameterized classes

وتسمى احيانا القوالب Templates

صف 1 اللائحة List يمثل مجموعة من أغراض التابعة لصف 2 هذا الصف 2 يصبح وسيط (بارمتر) لصف 1

حيث نسمي الصف 1 صف ذو وسيط (بارامتر)

لا يمكن استخدام الصف ذو البرامتر مباشره لأنه يملك بارامتر نمط لا يعني شيئا .

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

والشكل يوضح مخطط ال UML لمثل هذا النوع من الصفوف

حيث لدينا لائحة حسابات عبرنا عنه بصف باللائحة الذي مررنا اليه صف accounts كوسيط

[a385bbb735.gif

تم تعديل هذه المشاركة بواسطة nardien28 في 10 أغسطس 2006 في 14:50

سيمضي ركبنا العملاق لن يركع .. بإيمان لغير الحق لا يصدع

عزيزا شامخا كالمجد بل أروع .. فسجل أيها التاريخ ما تسمع :

فلسطين لنا الآمال والمطمع .. نعاهد أن نحررها وأن ترجع

ونقسم نستعيد الأرض أو نصرع .. ويبقى رمزنا الزيتون والمدفع

Palestine.gif

#13
List<List<? extends Shape>> history

فكرة جميلة أن أضع List داخل List ...

أيضا أخي nardien28 هل نسيت

List<List<? super Circle>> history

عندها يمكن تمرير أغراض التي تكون Circle ابن لها ... يعني Shape

SCJP 5.0

#14

منييييييييح .... في حدا عميقرأ ومتابع معي

سيمضي ركبنا العملاق لن يركع .. بإيمان لغير الحق لا يصدع

عزيزا شامخا كالمجد بل أروع .. فسجل أيها التاريخ ما تسمع :

فلسطين لنا الآمال والمطمع .. نعاهد أن نحررها وأن ترجع

ونقسم نستعيد الأرض أو نصرع .. ويبقى رمزنا الزيتون والمدفع

Palestine.gif

#15

كملي جزاكي الله كل خير متابعيين كثير والشرح جميل وواضح

لست متواجد بشكل يومي

#16

بالفعل الموضوع جد رائع .. من زمان لم نجد مثل هذه المواضيع في منتدى الجافا ..

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

نحن متابعون إن شاء الله

فحنوت ألثم جرحه الرعافَ فانتكأت جراحي..

وهمت على خدي الدموع فقلت يا روحي وراحي..

هلّا رحمتَ قلوبنا .. وعدلت عن هذا الرّواحِ ِ ..؟

فأجابني البطل المسجّى هازئاً بيَ .. باقتراحي

كفكف دموعك ليس في عبراتك الحرّى ارتياحي

هذي سبيلي .. إن صدقت محبتي .. فاحمل سلاحي

Sun Certified Java Programmer

#17

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

11_03_06_12_48_57_1142110137Image(_66).jpg

#18

اختي شكراً لمثل هذه المواضيع ولكن الافضل كتابة المصطلحات بالانجليزي

فانا اعرف generics ومادريت انها نفسها عموميات إلا من هذا الموضوع

عالعموم انا مستغرب من كون الـgenerics لم تضاف للـJDK إلا في نسخته الأخيره ،

لأني اعتقد بأن الجافا هي وريث السي ++

والـgenerics موجوده في السي++ باسم Templates

الميزه الأساسيه من الـgenerics هي تنفيذها وقت الRunTime ،

فطول الكود تظل formal type parameter or <E> 0

ووقت التنفيذ تتحدد بحسب الـObject المرسل .

وبهذا نتخلص من مسألة الـcasting في البرامج

#19

طلب بسيط من الأخ رامي أو مجدي .. تعديل العنوان الى

العموميات في جافا Generics

لأن العنوان كما قال الأخ {العيسى} ليس واضح

سيمضي ركبنا العملاق لن يركع .. بإيمان لغير الحق لا يصدع

عزيزا شامخا كالمجد بل أروع .. فسجل أيها التاريخ ما تسمع :

فلسطين لنا الآمال والمطمع .. نعاهد أن نحررها وأن ترجع

ونقسم نستعيد الأرض أو نصرع .. ويبقى رمزنا الزيتون والمدفع

Palestine.gif

#20

لوسمحتم عندي بس سؤال الحين الي يعرف فاهم templetes in ++c اهيا نفsiا generec in java

#21

نعم نفس الفكره ونفس البنية و كما وضع بعض الأخوة دروسا عن الـTempelets في قسم منتدى C و ++C

سيمضي ركبنا العملاق لن يركع .. بإيمان لغير الحق لا يصدع

عزيزا شامخا كالمجد بل أروع .. فسجل أيها التاريخ ما تسمع :

فلسطين لنا الآمال والمطمع .. نعاهد أن نحررها وأن ترجع

ونقسم نستعيد الأرض أو نصرع .. ويبقى رمزنا الزيتون والمدفع

Palestine.gif

#22
اقتباس
لوسمحتم عندي بس سؤال الحين الي يعرف فاهم templetes in ++c اهيا نفsiا generec in java

هممم...

أعتقد بوحود اختلافات.....

#23
حسام الملحم أبومازن كتب:
هممم...

أعتقد بوحود اختلافات.....

مثل ماذا ، أنا كتبت برنامجين بالسي++ والجافا ولم ألاحظ أختلاف !

#24

هممممم..

نعم،، معك حق،،، عند الكتابة ربما لا يوجد فرق... لكن هو فرق جوهري. ووجدت لك شرحا مفيدا هنا:

http://java.sun.com/developer/technicalArt.../J2SE/generics/

العموميات في جافا ليست إلا تنقيح وقت الترجمة أو وقت Compile time والفئات تبقى كما هي.. أما في سي ++ فهي آلة وظيفتها عمل فئة شبيهة باستخدام تصميم معين أو Template.. الفرق أنه في سي++ سيكون عندك فئة جديدة كلما استخدمت التصميم أو Template في فئة جديدة.

ولشرح هذا،، عندما تكتب:

List<Something> list = new ArrayList<Something>();

في سي++ سيعمل لك المترجم فئة جديدة ربما اسمها SomethingSpecialList وقد لا تدري عنها وهي مشابهة للفئة List.. أما في جافا، فالمترجم لن يصنع شيئا سوى التأكذ أنك استخدمت العموميات بشكل صحيح،، وبعدها يحذفها وكأنها غير موجودة!

وأعتذر عن التأخر.

#25

شكراً لك أبو مازن

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

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