В Java все находится в форме класса.
Если вы хотите использовать любой объект, тогда у вас есть две фазы:
Пример:
Object a;
a=new Object();
То же самое для концепции массива
Item i[]=new Item[5];
i[0]=new Item();
Если вы не дают секцию инициализации, тогда возникает NullpointerException
.
Прямой из первых уст (Hejlsberg):
Идеально все интерфейсы универсального набора (например,
ICollection<T>
,IList<T>
) наследовались бы их неуниверсальным дубликатам, таким образом, что универсальные интерфейсные экземпляры могли использоваться и с универсальным и неуниверсальным кодом. Например, было бы удобно, еслиIList<T>
мог бы быть передан для кодирования, который ожидаетIList
.Как оказалось, единственный универсальный интерфейс, для которого это возможно,
IEnumerable<T>
, потому что [только 115] - контравариант: ВIEnumerable<T>
, параметр типа T используется только в "выходных" положениях (возвращаемые значения) а не во "входных" положениях (параметры).ICollection<T>
иIList<T>
использование T и во входных и выходных положениях и в тех интерфейсах являются поэтому инвариантными. (Как в стороне, они были бы контравариантом, если T использовался только во входных положениях, но это действительно не имеет значения здесь.)<... надрез...>
Так, для ответа на вопрос, IEnumerable<T>
наследовался от [1 110], потому что это может!:-)
Ответ для IEnumerable
: "потому что это может, не влияя на безопасность типов".
IEnumerable
интерфейс "только для чтения" - таким образом, не имеет значения, что универсальная форма более конкретна, чем неуниверсальная форма. Вы ничего не повреждаете путем реализации обоих. IEnumerator.Current
возвраты object
, тогда как IEnumerator<T>.Current
возвраты T
- это хорошо, поскольку можно всегда законно преобразовывать в object
, хотя это может означать упаковывать.
Сравнивают это с IList<T>
и IList
- можно звонить Add(object)
на IList
, тогда как это может быть недопустимо для какого-то конкретного IList<T>
(что-либо кроме [1 112] на самом деле).
Brad Abram занесенный в блог с ответом Anders об этом самом вопросе.
Это для обратной совместимости. Если Вы вызываете функцию.Net 1.1, которая ожидает ваниль IEnumerable, можно передать в универсальном IEnumerable.
Luckilly универсальный IEnumerator наследовался IEnumerator
старого стиля, я обычно реализую закрытый метод, который возвращает перечислитель, и затем передайте его и для старого и для нового стиля метод GetEnumerator.
private IEnumerator<string> Enumerator() {
// ...
}
public IEnumerator<string> GetEnumerator() {
return Enumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
return Enumerator();
}
Это - то, так, чтобы это работало с классами, которые не поддерживают дженериков. Кроме того, дженерики.NET не позволяют Вам сделать, вещам нравится бросок IList< долго> как IList< интервал>, таким образом, не универсальные версии интерфейсов могут быть довольно полезными при необходимости в фиксированном базовом классе или интерфейсе.