
- •Лекции по курсу "Технология программирования" (1-й семестр) Оглавление
- •Технология .Net Предыдущее состояние дел.
- •Главные компоненты платформы .Net (clr, cts и cls)
- •Общеязыковая среда выполнения (clr)
- •О бщая система типов и общеязыковые спецификации (cts и cls)
- •Библиотека базовых классов
- •Роль языка с#
- •Компоновочные блоки
- •Роль метаданных типов .Net
- •Роль манифеста компоновочного блока
- •Общая система типов.
- •Объектно-ориентированное программирование
- •Главные элементы объектно-ориентированного подхода
- •Дополнительные элементы ооп
- •Принципы объектно-ориентированного программирования.
- •Классы Инкапсуляция
- •Объект (экземпляр класса).
- •Ключевое слово this
- •Отношения между объектами.
- •Основные отличительные особенности класса
- •Спецификаторы доступа
- •Состав класса
- •Поля класса
- •Доступ к полям
- •Статические и экземплярные переменные
- •Методы (функции-члены класса)
- •Переменное число параметров метода
- •Статические методы
- •Конструкторы
- •Закрытые конструкторы или классы без экземпляров
- •Статические конструкторы.
- •Деструкторы
- •Абстрактные методы и классы.
- •Свойства
- •Индексаторы
- •Статические классы
- •Частичные классы
- •Рекомендации по программированию
- •Наследование Понятие наследования в программировании
- •Типы наследования
- •Наследование реализации
- •Определение наследующих классов
- •Уровень доступа protected и internal
- •Ссылка на объект базового класса
- •Протоклассы
- •Предотвращение наследования с помощью ключевого слова sealed.
- •Отношения между классами
- •Абстрактные классы.
- •Класс object
- •Функциональные замыкания
- •Разработка функциональных замыканий с помощью наследования
- •Разработка функциональных замыканий с помощью экземпляров класса
- •Заключение.
- •Полиморфизм
- •Полиморфизм наследующих классов.
- •Переопределение методов родительского класса. Раннее связывание.
- •Виртуальные методы и их переопределение.
- •Как вызывают виртуальные методы
- •Виртуальные функции и принцип полиморфизма
- •Перегрузка.
- •Перегруженные конструкторы
- •Рекомендации программисту.
Разработка функциональных замыканий с помощью наследования
На языке С# функциональное замыкание может быть реализовано несколькими способами. Первый способ - через наследование. Идея состоит в том, чтобы иметь базовый класс, "знающий" о функциональных замыканиях, и производный класс, выполняющий конкретную работу внутри замыкания. В качестве примера рассмотрим класс для отображения всплывающего окна. Создание абстрактного базового класса является здесь хорошей отправной точкой.
сlass Popup // абстрактный класс
{
Image region; //Область занимаемая окном
public:
Popup(Rectangle r)
{ /* сохранение координат и размеров открываемого всплывающего окна */};
virtual void Display(Graphics g)=0;
~Popup(){/* восстановление закрытой области */};
}
Если для отображения реального всплывающего окна породить класс от Popup, то компилятор автоматически будет вызывать конструктор и деструктор базового класса, которые сыграют роль вступления и заключения функционального замыкания.
class SetupPopupWindow: Popup
{
public:
SetupPopupWindow(): Popup(1, 10, 100, 100){ /* построение содержимого окна */ };
void Display()
{
// реализация функции базового класса для запоминания области экрана,
// занимаемой данным окном, и рисование самого окна
};
// Вызов деструктора базового класса, который восстановит изображение
// области экрана, закрытой окном
}
// использование всплывающего окна
main()
{
SetupPopupWindow help;
help.Display();
// …
};
Всякий раз, при создании объекта класса SetupPopupWindow, детали сохранения и восстановления экрана обрабатываются компилятором. Подобная процедура хорошо работает тогда, когда необходимо функциональное замыкание в специализированном классе, полученном через наследование. С помощью наследуемых функциональных замыканий можно решить много задач, но не все.
Разработка функциональных замыканий с помощью экземпляров класса
Альтернативный способ создания функциональных замыканий с помощью экземпляров класса заключается в использовании динамики создания объекта при выполнении программы. Это проще наследования, но имеет свои ограничения. Здесь, как и в технологии с использованием наследования, используется автоматический вызов конструкторов и деструкторов. При создании экземпляра класса компилятор вызывает конструктор класса. Когда экземпляр разрушается, то компилятор вызывает деструктор класса. Конструктор и деструктор могут вновь сыграть роль вступления и заключения. И действительно, конструктор отводит ресурсы, функции - члены манипулируют ими, а деструктор освобождает их. Поскольку компилятор гарантирует обязательный вызов деструктора при разрушении объекта, то можете быть уверены в том, что ресурсы не будут по ошибке "болтаться" в системе.
Рассмотрим следующую реализацию всплывающего окна.
class Popup
{
Rectangle region;
public:
Popup(Rectangle r){ /* сохранение области экрана закрываемое окном */ };
...
~Popup(){ /* восстановление закрытой области */ };
}
// использование всплывающего окна
main()
{
Popup window;
// …
}
Функциональные замыкания являются очень важным элементом системы обработки исключительных ситуаций в языке С#. Если во время выполнения программы возникает исключительная ситуация, то программа переходит за пределы локальной области видимости. В результате, система автоматически вызывает деструкторы для тех объектов, которые, в результате перехода, выходят из области видимости. Не используя надлежащим образом концепцию функционального замыкания, можно легко ввести ошибки в свою программу.