Информационные технологииStfw.Ru 🔍

Проектирование иерархии классов. Использование контейнерных классов. Перерисовка графической информации

🕛 22.05.2009, 13:45
Классы являются шаблонами, на основе которых создаются объекты. Каждый объект содержит данные и методы для работы с этими данными. Класс определяет, какие данные может содержать каждый объект этого класса, но не содержит самих данных. При создании экземпляра объекта класса его поля заполняются конкретными данными.
Поля данных класса представляют собой любые переменные, связанные с классом. Если поля и функции объявлены как public, они доступны за пределами класса.
После того как будет создан экземпляр объекта, к полям класса можно осуществлять доступ с помощью синтаксиса объект.имя_поля.

Новые классы могут наследовать содержание (данные и методы) уже существующих классов. Такой новый класс называется производным. Класс, от которого он наследует, называется базовым. На основе наследования создаются иерархии классов. Проектирование иерархий классов - основа методологии объектно-ориентированного программирования.
Абстрактные классы содержат абстрактные методы - методы без реализации. Экземпляры таких классов не могут создаваться, но абстрактные классы часто используются в качестве базовых классов для иерархий классов, так как позволяют задать типовой набор функций, обязательный для реализации в производных классах. Такой абстрактный класс содержит обобщённую модель классов определённого назначения и ссылки на его тип могут использоваться в функциях, которым впоследствии будут передаваться экземпляры различных производных от него классов.

Контейнерные классы используются для хранения и обработки наборов объектов. Наиболее простой структурой данных такого рода является обычный массив. Массив в C# является экземпляром класса System. Array. System.Array имеет то преимущество, что он обеспечивает эффективный доступ к отдельному элементу по его индексу. Однако Array обладает недостатком, заключающимся в необходимости указания его размера при создании экземпляра класса. После его создания не существует возможности добавлять, вставлять или удалять элементы. .NET поддерживает множество других контейнерных классов, которые полезны в различных обстоятельствах.
За исключением System.Array, все классы структур данных располагаются в пространстве имён System.Collections. В .NET 2.0 добавилось пространство имён System.Collections.Generic, в котором находятся параметризованные реализации контейнерных классов. Таким классам при создании в качестве параметра, передаваемого в угловых скобках, указывается тип данных, который будет храниться в контейнере. В число этих классов входит класс List, реализующий динамический массив (массив переменного размера) для данных определённого типа. Если при инициализации такого массива указать в качестве параметра определённый класс, то массив можно будет использовать для хранения объектов этого класса и классов, производных от него.
Класс List может быть проинициализирован следующим образом для хранения динамического массива экземпляров любых классов, производных от класса Figure:
List<Figure> array;

array = new List<Figure>();

После этого в контейнер можно добавлять элементы при помощи метода Add(), которому передаётся ссылка на экземпляр добавляемого объекта.
Число элементов, в текущий момент содержащихся в List, может быть получено с помощью свойства Count:
int n = array.Count;
Для перебора всех элементов динамического массива удобно использовать оператор языка C# foreach :

foreach (Figure f in array) { … }

Блок в фигурных скобках выполняется для всех элементов array, ссылка на которые поочерёдно помещается в переменную (в данном случае - f), доступную внутри блока. Для доступа к элементам List можно использовать и обычную индексную операцию - [].

Операционная система Windows и среда .NET не обеспечивают приложениям сохранение графической информации, выводимой ими в свои окна. В ситуациях перекрытия этих окон другими окнами и их сворачивания ранее выведенная информация будет исчезать, если приложение не обеспечит восстановление содержания окна. Для этих целей предназначено событие Paint, которое должны обрабатывать классы форм и управляющих элементов для восстановления своего содержания. Данное событие генерируется, когда содержание окна должно быть обновлено, в первый раз - при первом отображении окна. Обработчик события Paint получает второй аргумент типа PaintEventArgs, поле Graphics которого содержит объект типа Graphics, через который должны выполняться в этом обработчике операции графического вывода. Обратите внимание на указанное обстоятельство - в обработчике события Paint Graphics не должен запрашиваться через метод CreateGraphics.

Рекомендации

Для создания новых классов в проектах Visual Studio.NET можно использовать команду «Project» - «Add class…» . Visual Studio предлагает указать имя файла, в котором будет сохранён новый класс с соответствующим именем.

1. Базовый класс для иерархии геометрических фигур рекомендуется сделать абстрактным классом.
При этом заголовок класса может выглядеть следующим образом:

abstract class Figure

Класс должен как минимум содержать данные, хранящие информацию о двух точках, задающих размеры блока геометрической фигуры, конструктор класса, получающий эти точки в качестве аргументов, и абстрактные методы Draw, DrawDash, Hide, которые должны будут обеспечивать рисование, рисование пунктиром и стирание фигур. Абстрактные методы задаются с ключевым словом abstract и не содержат тела метода. В производных классах эти методы будут получать реализацию, соответствующую типу конкретной фигуры. При этом они объявляются с использованием ключевого слова override . Пример объявлений абстрактного метода в базовом классе и его реализации в производном классе:
public abstract void Draw(Graphics g);

public override void Draw(Graphics g) {…}

Функции рисования должны получать в качестве аргумента объект Graphics, который им должна передавать форма, в которой будет рисоваться фигура.
Также в классе Figure можно уже поместить реализацию метода MouseMove, который получая от формы Graphics и координаты мыши, будет перемещать фигуру в новое положение, последовательно стирая её в исходном положении, изменяя координаты второй точки, задающей фигуру, и отображая фигуру в новом положении пунктиром. Также можно поместить в этот класс вспомогательный метод для нормализации координат прямоугольника, которая может требоваться для корректного вызова функций рисования. Чтобы метод в C# мог изменять значения переменных, переданных ему через аргументы, при объявлении этих аргументов и их передаче в метод должен использоваться префикс ref, обеспечивающий передачу аргумента по ссылке, а не по значению. Например, заголовок функции нормализации двух пар координат может быть следующим:

public void norm(ref int x1, ref int y1, ref int x2, ref int y2)

2.
Класс, моделирующий прямоугольник, должен быть объявлен производным от класса фигуры и должен содержать соответствующую реализацию абстрактных методов, объявленных в классе фигуры. Конструктор класса должен получать координаты углов прямоугольника и передавать их классу точки. Передача аргументов конструктору базового класса выполняется с использованием ключевого слова base. Пример:

public Rect(Point point1, Point point2) : base(point1, point2) {}

3.
Динамический массив следует сделать полем класса Form2 и проинициализировать это поле в конструкторе класса Form2.
При нажатии на левую кнопку мыши должен создаваться экземпляр класса прямоугольник, при перемещении мыши он должен использоваться для прорисовки перемещения, при отпускании левой кнопки должен рисоваться окончательный вид прямоугольника и он должен добавляться к динамическому массиву.
Код класса формы следует очистить от всех деталей, связанных с рисованием прямоугольников и обработкой их координат. Он должен лишь управлять объектами, выполняющими эти действия.
4.
Для восстановления информации в окне следует реализовать в классе Form2 обработчик события Paint. Этот метод должен перебирать все элементы динамического массива и перерисовывать их.

После этого в конец блока, обрабатывающего добавление нового прямоугольника в массив, следует добавить вызов метода Invalidate(), который также инициирует перерисовку окна. Этот вызов обеспечит устранение дефектов рисунка, которые могут появляться в процессе добавления новых элементов к рисунку.

Си: C/C++   Теги:

Читать IT-новости в Telegram
Информационные технологии
Мы в соцсетях ✉