إذا كنت سأخبرك بشكل مباشر ما هي الأدوية العامة، فلا أستطيع حقًا أن أطرح عليك سؤالًا:
حدد فئة نقطة إحداثية يمكنها حفظ أنواع مختلفة من البيانات، مثل الأعداد الصحيحة وأنواع النقاط العائمة وأنواع السلسلة.
نظرًا لأن نوع المتغير غير مؤكد في البداية، فمن السهل التفكير في استخدام الفئة الأصلية لجميع الأنواع، أي فئة الكائن بدلاً من ذلك.
لا مزيد من الهراء، استخدم الكود ليعكس ذلك
مثال 1: استخدم الكائن لتنفيذ إدخال نوع بيانات غير مؤكد
// استخدم الكائن لتمثيل الأنواع غير المؤكدة
النقطة العامة (الكائن x، الكائن y) {
this.setX(x);
this.setY(y);
}
مجموعة الفراغ العام (كائن x) {
this.x = x;
}
الكائن العام getX () {
العودة س؛
}
مجموعة الفراغ العام Y (الكائن y) {
this.y = y;
}
الكائن العام getY () {
العودة ذ؛
}
}
// فئة الاختبار
عرض الطبقة العامة {
public static void main(String[] args) {
System.out.println("استخدم أرقام الفاصلة العائمة لتمثيل الإحداثيات:");
النقطة ع = نقطة جديدة(12.23,23.21);
// هنا، يتم تحويل فئة الكائن إلى فئة مزدوجة، ثم يتم إخراجها تلقائيًا من العلبة.
System.out.println("إحداثيات X" + (مزدوج)p.getX());
System.out.println("إحداثيات Y" + (مزدوج)p.getY());
System.out.println();
System.out.println("استخدم الأعداد الصحيحة لتمثيل الإحداثيات:");
النقطة p2 = نقطة جديدة(12, 23);
System.out.println("إحداثيات X" + (عدد صحيح)p2.getX());
System.out.println("إحداثيات Y" + (عدد صحيح)p2.getY());
System.out.println();
System.out.println("تمثيل الإحداثيات كسلسلة:");
Point p3 = new Point("خط عرض 29 درجة شمالًا"، "خط طول 113 درجة شرقًا");
System.out.println("إحداثيات X" + (سلسلة)p3.getX());
System.out.println("إحداثيات Y" + (سلسلة)p3.getY());
}
}
يجب أن تفهم بوضوح النوع الذي تمر به، ثم قم بإلقائه قبل أن تتمكن من استخدامه.
على الرغم من أن هذا يلبي الطلب، إلا أنه يتضمن أيضًا عاملاً غير آمن. لماذا يُقال إنه ضمني؟
على سبيل المثال، نستخدم نقطة جديدة (12.23، "خط عرض 29 درجة شمالًا") لإنشاء كائن نقطة
ثم استخدم (Double) لتحويله إلى الأسفل ماذا ستكون النتيجة؟
نعم، سوف يمر التجميع، ولكن بمجرد تشغيله، سيحدث استثناء في تحويل النوع
من السهل أيضًا تجنب استثناءات تحويل الفئة، ما عليك سوى استبدال تعريف الكائن بتعريف نوع ثابت (مثل: String x وString y)، بحيث يتم الإبلاغ عن خطأ أثناء التجميع.
ومن ثم يمكنك العثور على الأخطاء وإجراء التصحيحات
ولكن بعد ذلك لن نكون قادرين على تلبية الطلب.
من أجل تجنب المخاطر الأمنية واستبدال أنواع البيانات المختلفة، قدم هؤلاء الأشخاص الموهوبون مفهوم الأدوية الجنيسة في JDK1.5
دعونا نرى كيفية إعادة كتابة الكود أعلاه باستخدام الأدوية العامة
مثال 2: فئة عامة
عرض الطبقة العامة {
public static void main(String[] args) {
System.out.println("استخدم أرقام الفاصلة العائمة لتمثيل الإحداثيات:");
// بعد إعادة الكتابة باستخدام الأدوية العامة، ليست هناك حاجة لإجراء تحويل تنازلي على البيانات المستخدمة.
Point<Double> p = new Point<Double>(12.23,23.21);
System.out.println("إحداثيات X" + p.getX());
System.out.println("إحداثيات Y" + p.getY());
System.out.println();
System.out.println("استخدم الأعداد الصحيحة لتمثيل الإحداثيات:");
Point<Integer> p2 = new Point<Integer>(12, 23);
System.out.println("إحداثيات X" + p2.getX());
System.out.println("إحداثيات Y" + p2.getY());
System.out.println();
System.out.println("تمثيل الإحداثيات كسلسلة:");
Point<String> p3 = new Point<String>("خط عرض 29 درجة شمالًا"، "خط طول 113 درجة شرقًا");
System.out.println("إحداثي X" + p3.getX());
System.out.println("إحداثيات Y" + p3.getY());
}
}
إذا مررنا أنواعًا مختلفة من البيانات عمدًا في هذا الوقت:
Point<Double> p = new Point<Double>("خط عرض 29 درجة شمالا"،12.22);
ثم سيتم الإبلاغ عن خطأ أثناء التجميع
على الرغم من تعريف الأدوية العامة، إذا لم تستخدم الآلية العامة في المنشئ، فسوف تتعامل مع البيانات على أنها كائن.
والغرض من ذلك هو التوافق بشكل أساسي مع الرموز القديمة قبل JDK1.4، مثل
النقطة ع = نقطة جديدة(22.11,23.21);
نتيجة التشغيل النهائية هي نفسها، ولكن ستتم مطالبتك برسالة تحذير أثناء التجميع.
مثال 3: الطرق العامة
كما ترون من المثال أعلاه، بمجرد تحديد نوع الكائن في المنشئ، سيتم استخدام نفس النوع في الفصل بأكمله
يتم استخدام المثال الأكثر شيوعًا في إطار عمل المجموعة، مثل: ArrayList<Integer> al = new ArrayList<Integer>();
في هذا الوقت، كافة أنواع الكائنات التي يتم تشغيلها في al هي أعداد صحيحة.
ومع ذلك، في بعض الأحيان لا نريد إصلاح كائن التشغيل، ولكننا نريد استخدام التكنولوجيا العامة بشكل أكثر مرونة.
في هذا الوقت، يمكنك تجربة الطريقة العامة
عرض باطل <E> عام (E e) {
System.out.println(e);
}
}
عرض الطبقة العامة {
public static void main(String[] args) {
طباعة ع = طباعة جديدة ()؛
ص. طباعة (12)؛
p.print("مرحبا");
p.show(new Integer(33));
ص.عرض(23);
}
}
في الواقع، بهذه الطريقة، لا يوجد فرق كبير عن استخدام كائنات الكائن في الأساليب.
علاوة على ذلك، بعد JDK1.5، تمت إضافة وظيفة الفتح التلقائي، مما يلغي الحاجة إلى التحول التنازلي.
مثال 4: الواجهة العامة
// طريقة التنفيذ الأولى:
فئة InterDemo1 تنفذ Inter<String> {
طباعة باطلة عامة (سلسلة t) {
System.out.println("طباعة:" + t);
}
}
// طريقة التنفيذ الثانية:
فئة InterDemo2<T> تنفذ Inter<T> {
طباعة باطلة عامة (T t) {
System.out.println("طباعة:" + t);
}
}
عرض الطبقة {
public static void main(String[] args) {
InterDemo1 id1 = new InterDemo1();
id1.print("مرحبا");
InterDemo2<Integer> id2 = new InterDemo2<Integer>();
id2.print(new Integer(23));
}
}
هناك طريقتان لتنفيذ واجهة عامة، إحداهما هي تحديد النوع العام عند تنفيذها.
والآخر هو الاستمرار في استخدام الأدوية العامة وتحديد النوع العام أثناء البناء.