سؤال

إليك واجهة:

public interface Foo<T> extends Comparable<Foo<T>>  {
   ...
}

وهناك بعض الفصول تنفيذ هذه الواجهة:

public class Bar extends Something implements Foo<Something> {
    public Vector<Foo<Bar>> giveBar() {
        ...
    }
}

public class Boo extends SomethingElse implements Foo<SomethingElse> {
    public Vector<Foo<Boo>> giveBoo() {
        ...
    }
}

والآن أريد أن تبقي حفنة من فوس (التي قد تكون حقا فوس أو بوس) داخل النواقل.

Bar bar = new Bar();
Boo boo = new Boo();
Vector<Foo<?>> vector;
if (...) 
   vector = bar.giveBar();
else
   vector = boo.giveBoo();

وأحصل على:

Type mismatch: cannot convert from Vector<Foo<SomethingElse>> to Vector<Foo<?>>

والشيء نفسه ينطبق على:

Vector<Foo> vector;
if (...) 
   vector = giveBar();
else
   vector = giveBoo();

هل الفائقة أن كلا من المحامين وبو تمديد الحل الوحيد لهذه المشكلة؟

هل كانت مفيدة؟

المحلول

وماذا عن هذا الرمز يتلخص هو:

Vector<A> vector = new Vector<B>();

في هذه الحالة B يمتد A، ولكن هذا لا يسمح لأنواع غير متطابقة. أن نوضح لماذا لم تنجح هذه الطريقة، تخيل البرمجية التالية:

Vector<Vector<?>> vector = new Vector<Vector<String>>();
vector.add(new Vector<Integer>());

ونوع المتغير هو من ناقلات ناقلات من نوع غير معروف . وما يجري المسندة إليه هو ناقلات ناقلات السلاسل . يضيف السطر الثاني من ناقلات من الأعداد الصحيحة إلى ذلك. نوع المكون من Vector<?> متغير، التي تقبل Vector<Integer>. لكن Vector<String> نوع العنصر الموجه الفعلي، والذي لا. إذا لم المترجم يعترض على الاحالة على السطر الأول، فإنه يسمح لك لكتابة السطر الثاني غير صحيحة دون أن تكتشف.

الوراثة

وC # الصورة لديها قيود مماثلة، ولكن الفرق هو أن فئة عامة في C # مخازن نوع المكون، في حين ينسى جافا أنواع المكونات عند التحويل البرمجي التعليمات البرمجية.

ملاحظة - لماذا على وجه الأرض الذي تستخدمه Vector بدلا من LinkedList أو ArrayList؟ هل لأن هناك خيوط القضايا المطروحة؟

نصائح أخرى

ويمكنك استخدام

Vector<? extends Foo<?>> vector;
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top