6_C#_интерфейсы_&_ArrayList

advertisement
Тип интерфейс
 Интерфейс – именованный набор методов, не имеющих реализации.
 Определение интерфейса может содержать
• методы (только сигнатуры)
• свойства
• индексаторы
• события
 В классе, реализующем интерфейс, должны быть реализованы все
методы интерфейса.
 Интерфейс описывает общую функциональность различных типов.
public interface System.IDisposable {
void Dispose();
}
public interface System.IComparable {
int CompareTo ( Object obj );
}
Определение интерфейса
 Имя интерфейса рекомендуется начитать с буквы I.
 Методы интерфейса не имеют модификаторов доступа. По
умолчанию все методы интерфейса являются открытыми (public) и
виртуальными (virtual).
 Интерфейс может быть унаследован от нескольких интерфейсов.
public interface ICollection : IEnumerable {
int Count {get;}
bool IsSynchronized {get;}
object SyncRoot {get;}
void CopyTo( Array array, int index );
}
public interface IEnumerable {
IEnumerator GetEnumerator();
}
Реализация интерфейсов
 В типе, реализующем интерфейс, должны быть реализованы все
методы интерфейса и все методы унаследованных интерфейсов.
 Методы интерфейса могут быть реализованы явно и неявно.
• При неявной реализации в типе определяется метод с
соответствующей сигнатурой без указаний на интерфейс. Этот метод
виден как обычный метод типа.
• При явной реализации в определении метода в типе явно
указывается имя интерфейса. Тип может содержать одновременно
явную реализацию интерфейса и метод с тем же именем и
сигнатурой. При помощи явной реализации можно реализовать два
интерфейса с одинаковыми методами.
public class ArrayList : IList, ICollection, IEnumerable, ICloneable
{
IEnumerator GetEnumerator() { … }
…
}
Реализация интерфейсов -2
 Класс, реализующий интерфейс, может наследовать реализацию
методов интерфейса от своих базовых классов.
public interface Intf1
{ void F0();
void F1();
}
public interface Intf2
{ void F0();
void F2();
void F3();
}
public class A : Intf1
{ public void F0 ()
{ Console.WriteLine
public virtual void
{ Console.WriteLine
public void F2()
{ Console.WriteLine
}
static void Main(string[] args)
{ A a = new A();
Dr d = new Dr();
a.F0();
// A.F0
d.F0();
// A.F0
// d.F3();
// D does not contain a definition for 'F3'
явная
реализация
метода
интерфейса
Intf1 it1 = a;
Intf1 it11 = d;
it1.F0();
// A.F0
it11.F0();
// A.F0
("A.F0");}
F1 ()
("A.F1");}
Intf2 it2 = d;
it2.F0();
it2.F3();
("A.F2");}
public class Dr : A, Intf2
{
void Intf2.F0()
{ Console.WriteLine ("Dr.F0");}
public override void F1 ()
{ Console.WriteLine ("Dr.F1");}
void Intf2.F3()
{ Console.WriteLine (“Dr.F3");}
}
// Dr.F0
// Dr.F3
A ar = it11 as A;
Dr dr = it11 as Dr;
if (ar == null) Console.WriteLine("ar == null");
else Console.WriteLine("ar != null");
// ar != null
Console.WriteLine(object.ReferenceEquals(ar, dr));
// true
Console.WriteLine(object.ReferenceEquals(ar, it11));
// true
}
Интерфейс как параметр или как тип
возвращаемого значения
 Возможно неявное преобразование класса к реализуемому им
интерфейсу.
Метод класса System.Collections.ArrayList
public virtual void Sort( IComparer comparer );
как значение параметра принимает ссылку на объект любого типа,
который реализует интерфейс IComparer.
public interface IComparer {
int Compare( object x, object y );
}
Особенности реализации интерфейсов
 Если интерфейс реализован с помощью невиртуального метода, то
при вызове через интерфейс будет вызван метод, соответствующий
статическому типу в момент приведения к типу интерфейса.
 Даже если базовый класс реализовал интерфейс, то производный
класс снова может реализовать интерфейс.
public interface I { void f(); }
public class A : I {
public void f() { Console.WriteLine("A.f"); }
}
public class B : A,I {
public new void f() { Console.WriteLine("B.f"); }
}
I i1 = new
I i2 = new
i1.f(); //
i2.f(); //
A();
B();
A.f
B.f
Интерфейс IDisposable
 Классы, требующие явного освобождения ресурсов, могут
предоставлять интерфейс IDisposable
interface IDisposable {
void Dispose();
}
 Оператор
using - краткая форма try-finally
class A : IDisposable { }
class B : IDisposable { }
using(a = new A())
using(b = new B())
{
// …
}
a = new A();
try {
b = new B();
try {
…
}
finally { b.Dispose(); }
}
finally {
a.Dispose();
}
Оператор foreach
итерационная
переменная
оператор
foreach (type identifier in expression) statement
тип итерационной
переменной
массив или
коллекция
 Коллекция (expression)
• должна иметь тип class, struct или interface;
• в типе, который имеет коллекция, должен быть определен открытый
экземплярный метод GetEnumerator().
 В типе, который возвращает метод GetEnumerator(), должны быть определены
• свойство Current { get;}, которое дает доступ к текущему элементу
коллекции;
• метод bool MoveNext(), который возвращает значение
• true - если в коллекции еще есть элементы;
• false - в противном случае.
 Тип свойства Current (тип элементов коллекции) должен допускать неявное
преобразование к типу <type>.
Интерфейсы System.IEnumerable и
System.Collections.IEnumerator
 В классе, реализующем интерфейс IEnumerable, можно использовать
оператор foreach.
 Интерфейс IEnumerable реализован в классе System.Array и классахколлекциях.
public interface IEnumerator {
object Current {get;}
bool MoveNext();
void Reset();
}
public interface IEnumerable {
IEnumerator GetEnumerator();
}
Интерфейс System.Collections.IEnumerator
 Итераторы(еnumerators) используются только для чтения данных
из коллекции, их нельзя использовать для изменения коллекции.
 При инициализации enumerator позиционируется перед первым
элементом коллекции. Вызов Current в этой позиции порождает
исключение. Необходимо вызвать MoveNext перед тем, как
обратиться к Current. Reset возвращает enumerator в позицию
инициализации.
 Метод MoveNext перемещает Current к следующему элементу.
Current возвращает один и тот же объект до тех пор, пока не будут
вызваны MoveNext или Reset.
 MoveNext возвращает false, когда enumerator позиционируется за
последним элементом коллекции. Если последний вызов MoveNext
возвращает false, вызов Current бросает исключение.
Интерфейсы System.IComparable,
System.Collections.IComparer
public interface IComparable {
int CompareTo( object y );
}
public interface IComparer {
int Compare( object x, object y );
}
Возвращаемое значение:
<0
x<y
0
x==y
>0
x>y
( в методе CompareTo x – вызывающий объект)
 Интерфейс IComparable реализован в типах string, enum,,double, Int32,…
 Интерфейсы IComparer и IСomparable используются методами Sort.
• В System.Array 8 перегрузок статического метода Sort
• B System.Collections.ArrayList 3 экземплярных метода Sort
Реализация System.IComparable в типах Double и
Single
 Интерфейс IComparable реализован в типах float, double
 Возвращаемое значение мeтодов int CompareTo (object value) :
отрицательно
0
положительно
• значение вызывающего объекта меньше value ;
• вызывающий объект - NaN, value – число.
• значение вызывающего объекта равно value ;
• и вызывающий объект, и value имеют значение
NaN, бесконечность или минус бесконечность.
• значение вызывающего объекта больше value ;
• вызывающий объект - число, value равно NaN ;
• value равно null.
Реализация System.IComparable в типе string
 Интерфейс IComparable реализован в типе string. Сравнение
выполняется с учетом регистра и текущих региональных установок
(current culture).
 Возвращаемое значение в мeтоде int CompareTo (object value)
отрицательно
0
положительно
• значение вызывающего объекта меньше value ;
• значение вызывающего объекта равно value ;
• значение вызывающего объекта больше value ;
• value равно null.
Методы Sort в System.Array
 В System.Array определено 8 перегруженных методов Sort() для
сортировки одномерных массивов.
 В элементах одномерного массива должен быть реализован один из
интерфейсов IComparable или IComparer
public static void Sort( Array array );
// сортирует массив c
// использованием IComparable
public static void Sort( Array array, IComparer comparer ); // сортирует c
// использованием IComparer ( если comparer==null,
// используется IComparable)
public static void Sort ( Array array, int index, int length );
// сортирует подмножество элементов массива
public static void Sort( Array keys, Array items ); // сортирует первый
// массив и переставляет элементы второго в среднем
// за O(nlog n) операций, значение items может быть
// равно null.
Класс System.Collections.ArrayList
 Класс ArrayList используется для работы с массивом элементов,
число которых изменяется динамически.
 Непосредственный базовый класс – System.Object.
public class ArrayList : IList, ICollection,
IEnumerable, ICloneable {…}
 Конструкторы:
public ArrayList();
public ArrayList( int capacity );
public ArrayList( ICollection c );
 Объем (capacity):
public virtual int Capacity {get; set;}
public virtual void TrimToSize();
Методы Sort в ArrayList
 Сортировка всей коллекции с использованием метода CompareTo()
интерфейса IComparable:
public virtual void Sort();
 Сортировка всей коллекции или ее части с использованием метода
Compare() интерфейса IComparer:
public virtual void Sort( IComparer comparer );
public virtual void Sort( int index, int count, IComparer comparer );
Download