Могут быть интерфейсы IReadable<out T> { T read(int index); }
, IWritable<in T> { void write(int index, T dat);
, ISplitReadWrite<out Tout, in Tin>:IReadable<Tout>,IWritable<Tin>
и IReadWrite<T>:ISplitReadWrite<T,T>
.
Если есть класс MyCollection<T>
, реализующий IReadWrite<T>
, тогда MyCollection<Cat>
может быть преобразованным в IReadable<Animal>
, IWritable<SiameseCat>
или ISplitReadWrite<Animal,SiameseCat>
. Обратите внимание, однако, что единственный IReadable<T>
, который даст элемент, который может быть сохранен в MyCollection<Cat>
, будет IReadable<Cat>
, единственный IWritable<T>
, который может обработать все, что может появиться в MyCollection<Cat>
, будет IWritable<Cat>
. Единственными формами ISplitReadWrite<Tout,Tin>
, которые позволили бы считывать элемент и записывать его обратно в ту же коллекцию без приведения, были бы те, в которых два типа были одинаковыми, и был реализован единственный такой тип by MyCollection<Cat>
будет ISplitReadWrite<Cat,Cat>
.
Обратите внимание, что можно иметь интерфейс с методами, которые можно было бы одинаково использовать с MyCollection<Animal>
и MyCollection<SiameseCat>
, например «поменять местами элементы в слотах i1 и i2. из той же коллекции », но такой интерфейс вообще не нуждается в параметре generi c . Id one имеет интерфейс IPermutable
, он может включать такие методы, как void swapItems(int i1, int i2);
, в сигнатурах которых не будет никаких типов generi c, и, следовательно, не потребуется включать в тип какие-либо общие c аргументы типа.