
- •Лекции по курсу "Технология программирования" (1-й семестр) Оглавление
- •Технология .Net Предыдущее состояние дел.
- •Главные компоненты платформы .Net (clr, cts и cls)
- •Общеязыковая среда выполнения (clr)
- •О бщая система типов и общеязыковые спецификации (cts и cls)
- •Библиотека базовых классов
- •Роль языка с#
- •Компоновочные блоки
- •Роль метаданных типов .Net
- •Роль манифеста компоновочного блока
- •Общая система типов.
- •Объектно-ориентированное программирование
- •Главные элементы объектно-ориентированного подхода
- •Дополнительные элементы ооп
- •Принципы объектно-ориентированного программирования.
- •Классы Инкапсуляция
- •Объект (экземпляр класса).
- •Ключевое слово this
- •Отношения между объектами.
- •Основные отличительные особенности класса
- •Спецификаторы доступа
- •Состав класса
- •Поля класса
- •Доступ к полям
- •Статические и экземплярные переменные
- •Методы (функции-члены класса)
- •Переменное число параметров метода
- •Статические методы
- •Конструкторы
- •Закрытые конструкторы или классы без экземпляров
- •Статические конструкторы.
- •Деструкторы
- •Абстрактные методы и классы.
- •Свойства
- •Индексаторы
- •Статические классы
- •Частичные классы
- •Рекомендации по программированию
- •Наследование Понятие наследования в программировании
- •Типы наследования
- •Наследование реализации
- •Определение наследующих классов
- •Уровень доступа protected и internal
- •Ссылка на объект базового класса
- •Протоклассы
- •Предотвращение наследования с помощью ключевого слова sealed.
- •Отношения между классами
- •Абстрактные классы.
- •Класс object
- •Функциональные замыкания
- •Разработка функциональных замыканий с помощью наследования
- •Разработка функциональных замыканий с помощью экземпляров класса
- •Заключение.
- •Полиморфизм
- •Полиморфизм наследующих классов.
- •Переопределение методов родительского класса. Раннее связывание.
- •Виртуальные методы и их переопределение.
- •Как вызывают виртуальные методы
- •Виртуальные функции и принцип полиморфизма
- •Перегрузка.
- •Перегруженные конструкторы
- •Рекомендации программисту.
Перегруженные конструкторы
Чаще всего перегрузка применяется при создании перегруженных конструкторов. Дело в том, что при реализации класса следует предоставить пользователю как можно больше вариантов создания экземпляров класса, обеспечивая тем самым максимально возможную гибкость при работе с классом. Рассмотрим класс для всплывающего окна в пакете графического пользовательского интерфейса. Необходимо реализовать следующие типы окон:
// окно со всеми параметрами по умолчанию
PopupWindow window;
// окно по указанным координатам
PopupWindow window_1(x,y);
// окно с указанными размерами
PopupWindow window_(x,y,width,height);
// окно, похожее на другое
PopupWindow window_3=window_2;
Реализация такого класса представлена в следующем листинге:
class PopupWindow
{
int x, y, width, height;
public:
PopupWindow();
PopupWindow(int, int);
PopupWindow(int, int, int, int);
PopupWindow(PopupWindow&);
};
// все значения по умолчанию
PopupWindow:: PopupWindow(){ x=y=100; width=height=100; };
// установить по умолчанию ширину и высоту
PopupWindow:: PopupWindow(int px, int py){ x=px; y=py; width=height=100; };
// инициализировать все переменные
PopupWindow:: PopupWindow(int px, int py, int w, int h){ x=px; y=py; width=w; height=h; };
// сделать один объект похожим на другой
PopupWindow:: PopupWindow(PopupWindow &pw){ x=pw.x; y=pw.y; width=pw.width; height=pw.height; };
Для выполнения указанных выше требований класс использует четыре перегруженных конструктора. Чем меньше пользователь должен знать о реализации класса, тем лучше класс. Перегрузка в этом смысле рпидаёт ему гибкость. Пользователь решает, какие переменные инициализировать явно, а какие установить по умолчанию. При программировании под Windows применяется можество классов, для которых указываются аргументы даже тогда, когда все значения используются по умолчанию. Перегрузка позволяет программистам не указывать постоянно длинный список аргументов.
Перегруженные конструкторы копирования часто вообще обеспечивают краткость при создании новых экземпляров класса. Можно указать, какие изменить параметры для копируемого объекта. Например:
PopupWindow::PopupWindow(PopupWindow &pw, int px, int py)
{
x=px;
y=py;
width=pw.width;
height=pw.height;
};
Приведённый код копирует некоторые или все переменные объекта, указанного ссылкой, но какие-то переменные нового (скопированного) объекта инициализирует по-другому. Можно определить неограниченное количество конструкторов копирования, но все они должны различаться своими параметрами.
Рекомендации программисту.
Как виртуальные должны быть описаны методы, которые выполняют во всех классах иерархии одну и ту же функцию, но, возможно, разными способами. Пусть, например, все объекты иерархии должны уметь выводить информацию о себе. Поскольку эта информация хранится в различных полях производных классов, функцию вывода нельзя реализовать в базовом классе. Естественно назвать ее во всех классах одинаково и объявить как виртуальную с тем, чтобы ее можно было вызывать в зависимости от фактического типа объекта, с которым работают через базовый класс.
Обычные (не виртуальные) методы переопределять в производных классах не рекомендуется, поскольку производные классы должны наследовать свойства своих базовых классов, а спецификатор new, с помощью которого переопределяется обычный метод, "разрывает" отношение наследования на уровне метода. Иными словами, невиртуальный метод должен быть инвариантен относительно специализации, то есть должен сохранять свойства, унаследованные из базового класса независимо от того, как конкретизируется (специализируется) производный класс.
Специализация производного класса достигается добавлением новых методов и переопределением существующих виртуальных методов.