На этом шаге мы рассмотрим назначение, создание и использование таких классов.
Обобщенный класс - это класс, в котором некоторые (или все) типы представлены обобщенными параметрами. Конкретные значения для типов данных определяются на этапе создания объекта класса. Зачем такие классы нужны и какая от них польза? Вообще, обобщенный класс представляет собой конструкцию еще более абстрактную, чем обычный класс. Например, мы хотим создавать объекты с двумя полями. Если мы описываем обычный класс, то в таком классе мы должны указать типы полей. Но если мы описываем обобщенный класс, то типы полей можно указать с помощью обобщенных параметров, а затем, уже при создании объекта, определяются значения типов. Получается, что обобщенный класс представляет собой некий шаблон для обычного класса. То есть он "инкапсулирует" в себе различные классы однотипной структуры - в данном случае это классы, у которых два поля, не важно, какого типа.
Обобщенные классы удобно использовать в тех случаях, когда объекты, с которыми предстоит иметь дело, должны иметь однотипную структуру, но при этом тип данных может быть разным. Допустим, нам необходимо хранить данные в виде массива и для этой цели предполагается использовать специальные объекты-контейнеры, содержащие соответствующий массив и имеющие методы для работы с данными из массива. Если так, то тип элементов массива отходит на второй план. Его можно реализовать через обобщенный параметр, а в самом обобщенном классе описать универсальные алгоритмы (реализовав их в виде методов), применимые для данных любого типа. А конкретный тип данных, которые будут храниться в контейнере, определяется на этапе создания объекта.
Как же описывается обобщенный класс? В принципе, так же, как и обычный (не обобщенный). Только в угловых скобках после названия класса указывается обобщенный параметр (или параметры), обозначающий тип данных. Этот параметр (или параметры) используется в теле класса, отождествляя собой некоторый тип (какой именно, становится понятно при создании объекта на основе класса). А объект класса тоже создается как обычный объект, но кроме названия обобщенного класса в угловых скобках после имени класса указывается значение (или значения) для обобщенных параметров. Шаблон описания обобщенного класса следующий:
class имя класса<параметр(ы) типа> { // Код класса }
При создании объекта на основе обобщенного класса используем следующий шаблон:
класс<тип(ы)> объект = new класс<тип(ы)>();
Фактически, если под названием класса подразумевать имя класса с угловыми скобками и указанными в них значениями типов данных, процесс создания объекта представляется традиционным.
Теперь рассмотрим программу, в которой есть примеры описания и использования обобщенных классов.
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace pr258_1 { // Обобщенный класс c одним параметром: class Alpha<X> { // Поле обобщенного типа: public X code; // Конструктор: public Alpha(X a) { code = a; } // Метод: public void show() { Console.WriteLine("Поле типа {0}: {1}", typeof(X).Name, code); } } // Обобщенный класс с двумя параметрами: class Bravo<X, Y> { // Поля обобщенного типа: public X first; public Y second; // Конструктор: public Bravo(X a, Y b) { first = a; second = b; } // Метод: public void show(){ Console.WriteLine("Первое поле типа {0}: {1}", typeof(X).Name, first); Console.WriteLine("Второе поле типа {0}: {1}", typeof(Y).Name, second); } } // Главный класс: class Program { static void Main() { // Создание объектов обобщенного класса: Alpha <int> A = new Alpha<int>(123); Alpha <string> B = new Alpha<string>("object B"); Alpha <char> C = new Alpha<char>('C'); // Вызов методов из объектов обобщенного класса: A.show(); B.show(); C.show(); Console.WriteLine(); // Создание объектов обобщенного класса: Bravo <int, char> objA = new Bravo<int, char>(123, 'A'); Bravo <string, bool> objB = new Bravo<string, bool>("objB", true); Bravo <char, char> objC = new Bravo<char, char>('B', 'C'); // Вызов методов из объектов обобщенного класса: objA.show(); objB.show(); objC.show(); // Задержка: Console.ReadLine(); } } }
Результат выполнения программы такой:
Рис.1. Результат работы приложения
Программа простая. В ней мы описываем два обобщенных класса: класс Alpha описан с одним обобщенным параметром (обозначен как X), а класс Bravo описан с двумя обобщенными параметрами (обозначены как X и Y). В описании классов обобщенные параметры указываются в угловых скобках после имени класса.
В классе Alpha есть поле code обобщенного типа X, а также метод show(), при вызове которого в консольном окне отображается информация о значении обобщенного параметра X и значении поля code. Также в классе Alpha есть конструктор с одним аргументом (типа X). Переданный конструктору аргумент присваивается в качестве значения полю code.
Класс Bravo подобен классу Alpha, но с поправкой на то, что в классе Bravo два обобщенных параметра (X и Y), два поля (поле first типа X и поле second типа Y), у конструктора два аргумента, а метод show() при вызове отображает значение параметров X и Y, а также значение полей first и second.
В главном методе создаются объекты классов Alpha и Bravo, и из этих объектов вызывается метод show(). Хочется верить, что результат выполнения соответствующих команд особых комментариев не требует.
На следующем шаге мы рассмотрим обобщенные структуры.