130 likes | 300 Views
Обобщенные классы. 2014. Обобщенные типы. О бобщенные классы представляют еще один вид полиморфизма – параметрический. Впервые появились в 1970-х в языке Клу (Барбара Лисков).
E N D
Обобщенные классы 2014
Обобщенныетипы Обобщенные классы представляют еще один вид полиморфизма – параметрический. Впервые появились в 1970-х в языке Клу (Барбара Лисков) Профессор Массачусетского технологического института (MIT) Барбара Лисков (BarbaraLiskov) получила престижную премию Тьюринга за вклад в теорию абстракции данных, которая упрощает создание сложных программ.
Обобщенные методы Чтобы написать обобщенный метод, сначала нужно написать обычныйметод, а потом заменить конкретный тип параметром. staticintindexOf<T>(T[] m, T k) { for (inti = 0; i < m.Length; i++) if (m[i].Equals(k)) returni; return -1; } staticintindexOf(char[] m, char k) { for (inti = 0; i < m.Length; i++) if (m[i] == k) returni; return -1; } Вывод типа – при вызове обобщенного метода компилятор может сам конкретизировать тип. int n = indexOf<int>(list, 35); int n = indexOf(list, 35);
Ограничения параметрического типа staticintindexOf<L, T>(L m, T k) where L: IList<T> { for (inti = 0; i < m.Count; i++) if (m[i].Equals(k)) returni; return -1; } Специфика параметров должна быть описана в ограничениях (ключевое слово where) where T: Name1, Name2,… // T наследует класс, интерфейс struct, // T – структурный тип class, // T – ссылочный тип new() // T имеет ctr() Форма ограничений
Обобщенные классы • publicclassRect<T> { public T Width { set; get; } public T Height { set; get; } publicdouble Square() { returnConvert.ToDouble(Width) * Convert.ToDouble(Height); } } Иным способом умножение объектов типа Т можно организовать при помощи интерфейса с методом умножения. Работа с классом Rect<T> Rect<float> sq = newRect<float> { Width = 4f, Height = 5f }; var s = sq.Square(); Первоначально обобщенные типы служили для типизации коллекций.
Пример: Обобщенный вектор publicclassVector<T> { const int CAPACITY = 100; T[] array; publicint Count { privateset; get; } public Vector() { array = new T[CAPACITY]; Count = 0; } publicvoid Add(T x) { array[Count++] = x; } • public T GetItem(inti) {return array[i]; } • public void SetItem(inti, T value) { • array[i] = value; • }
Индексатор Индексатор – это свойство с параметрами. В отличие от свойства индексатор не имеет собственного имени и объявляется при помощи слова this.
Пример: Вектор с индексатором publicclassVector<T> { const int CAPACITY = 100; T[] array; publicint Count { privateset; get; } public Vector() { array = new T[CAPACITY]; Count = 0; } publicvoid Add(T x) { array[Count++] = x; } public T this[inti] { get { return array[i]; } set { array[i] = value; } } }
Интерфейс Интерфейс – абстрактный класс, полностью лишенный реализации. Реализация – это поля и код методов. Интерфейс – это обязательство, которое берет на себя класс или структура. publicinterfaceIComparable { intCompareTo(objectobj); } publicinterfaceIComparable<T> { intCompareTo(T other); }
Сортировкаточек classPoint { publicint X { set; get; } publicint Y { set; get; } } classProgram { staticvoid Main(string[] args) { Point[] points = { newPoint { X = 3, Y = 3 }, newPoint { X = 2, Y = 4 },}; Array.Sort(points); } } Упорядочить точки не получится, т.к. их нельзя сравнивать.
Сортировкаточек Реализация классом Point интерфейса IComparable<T> позволяет методу Array.Sort() сравнивать точки, и теперь сортировка работает. classPoint: IComparable<Point> { publicint X { set; get; } publicint Y { set; get; } intIComparable<Point>.CompareTo(Point other) { return this.X – other.X; } }
Интерфейс IComparer<T> Реализация IComparableпозволяет сортировать точки только в каком-то одном порядке. Правило сравнения можно задать в постороннем объекте, реализующем интерфейс IComparer<T>. classXComparer : IComparer<Point> { publicint Compare(Point a, Point b) { returna.X - b.X; } } classYComparer: IComparer<Point> { publicint Compare(Point a, Point b) { returna.Y- b.Y; } } Сортировка с объектом-компаратором: Array.Sort(points, newXComparer());
Самостоятельно Замените индексатор в классе Vector<T> на такой, который бы позволил рассматривать вектор как двумерный массив. Для этого добавье в вектор свойство intSecondDimension – "ширина" строки двумерного массива. Добавьте в класс Vector<T> метод Sort(). Перегрузите метод Sort(IComparer<T> c)