
- •Глава 13. Включение, вложение и наследование классов
- •13.1. Включение объектов классов
- •13.2. Вложение классов
- •13.3. Наследование классов
- •13.4. Доступность членов класса при наследовании
- •13.5. Методы при наследовании
- •13.6. Абстрактные методы и абстрактные классы.
- •13.7. Опечатанные классы и методы
- •13.8. Применение абстрактых классов
13.7. Опечатанные классы и методы
Кроме абстрактных методов и абстрактных классов С# разрешает определять методы, свойства и классы, для которых невозможно наследование. В объявление такого метода, свойства или класса входит модификатор sealed (опечатанный, герметизированный). Опечатанный класс нельзя использовать в качестве базового класса. Опечатанный метод и опечатанное свойство при наследовании нельзя переопределить.
В базовой библиотеке классов .NET Framework много опечатанных классов. Программисты, работающие с библиотекой в качестве пользователей, не могут создавать собственные производные классы на основе опечатанных классов .NET Framework. Таким опечатанным библиотечным классам является класс string.
13.8. Применение абстрактых классов
Мы уже отметили, что нельзя создать объект абстрактного класса. Однако можно объявить ссылку с типом абстрактного класса. Такая ссылка может служить параметром метода и возвращаемым значением метода. В обоих случаях ссылка представляет объект того конкретного класса, который является производным от абстрактного.
В качестве примера обратимся ещё раз к абстрактному классу Figure и производным от него классам Rectangle и Triangle. В этих классах определены методы sguare(), возвращающие значения площадей объектов конкретных классов (не абстрактных). Следующий метод позволяет вывести значение любого объекта классов Triangle и Rectangle (программа 13_13.cs).
static void figSq(Figure f) { Console.WriteLine("Площадь = " + f.square()); }
Можно определять массивы ссылок с типами абстрактных классов. Значениями этих ссылок должны быть "адреса" объектов конкретных классов, реализующих базовый. Следующий метод возвращает ссылку с типом абстрактного класса:
static Figure figRec(Figure[] ar, int n) { return ar[n]; }
Параметры метода - ссылка на массив ссылок с типом Figure и целое n, определяющее индекс элемента этого массива. Возвращаемое значение метода - значение элемента массива. При обращении к методу в качестве аргумента используется ссылка на массив с типом элементов Figure. Каждому элементу массива-аргумента должно быть присвоено значение ссылки на объект конкретного класса, производного от Figure.
В следующем фрагменте программы 13_13.cs определён массив ссылок с типом Figure. Его элементам присвоены ссылки на объекты классов Rectangle и Triangle.
public static void Main()
{
Figure[] arF = new Figure[4];
arF[0] = new Rectangle(3.0, 4.0);
arF[1] = new Triangle(5.0, 4.0);
Triangle tri = new Triangle(8.0, 4.0);
arF[2] = tri;
Rectangle rec = new Rectangle(1.0, 3.0);
arF[3] = rec;
for (int i = 0; i < arF.Length; i++)
{
Figure f = figRec(arF, i);
figSq(f);
}
Console.WriteLine("Типы элементов массива: ");
foreach (Figure g in arF)
Console.WriteLine(g.GetType());
}
Результат выполнения программы:
Площадь = 12
Площадь = 10
Площадь = 16
Площадь = 3
Типы элементов массива: Rectangle
Triangle
Triangle
Rectangle
В программе элементы массива arF обрабатываются в двух циклах. В цикле с заголовком for переменной Figure f присваиваются значения, возвращаемые методом figRec(). Затем f используется в качестве аргумента метода figSq(). Тем самым выводятся значения площадей всех фигур, "адресованных" элементами массива arF.
В цикле с заголовком foreach перебираются все элементы массива arF и к каждому значению элемента, которое присвоено переменной Figure g, применяется метод GetType(). Результат - список названий классов, реализовавших абстрактный класс Figure.
Возможность присваивать элементам массива с типом абстрактного класса ссылок на объекты любых классов, реализовавших абстрактный, является очень сильным средством обобщения. Не меньше возможности обеспечивает применение ссылок с типом абстрактного класса в качестве параметров и возвращаемых методами значений.