Ответы_ТП
.pdfсоздаваемые программистом. В своих программах вы можете использовать для обработки ошибок "собственные" исключения. Для этого достаточно определить класс как производный от класса Exception. Как правило, опреде ляемые программистом исключения, должны быть производными от класса ApplicationException , "родоначальника" иерархии, зарезервированной для исключений, связанных с прикладными программами. Созданные вами производные классы не должны ничего реализовывать, по скольку одно лишь их существование в системе типов уже позволит использовать их в качестве исключений.
Классы исключений, создаваемые программистом, будут автоматически иметь свойства и методы, определенные в классе Exception и доступные для них. Конечно, один или несколько членов в новых классах можно переопределить.
//Создание пользовательского исключения для
//обнаружения ошибок при работе с объектами класса
//RangeArray.
using System;
// Создаем исключение для класса RangeArray. class RangeArrayException : ApplicationException {
//Реализуемстандартныеконструкторы , public RangeArrayException() : base() { }
public RangeArrayException(string str) : base(str) { }
//Переопределяемметод ToString()длякласса
//RangeArrayException.
public override string ToString() { return Message;
}}
// Улучшенная версия класса RangeArray. class RangeArray {
// Закрытые данные.
int[] а; // Ссылка на базовый массив. intlowerBound; // Наименьший индекс. intupperBound; // Наибольший индекс.
intlen; // Базовая переменная для свойства Length .
// Создаем массив с заданным размером, public RangeArray(int low, int high) { high++;
if(high <= low) {
throw new RangeArrayException(
"Нижний индекс не меньше верхнего."),
}
а = new int[high - low]; len = high - low; lowerBound = low; upperBound = --high;
}
// Свойство Length, предназначенное только для чтения, public int Length {
get { return len;
}}
//Индексатор для объекта класса RangeArray. public int this[int index] {
//Средство для чтения элемента массива,
get { if(ok(index)) {
return a[index - lowerBound]; } else {
throw new RangeArrayException(
"Ошибка нарушения границ диапазона.");
}}
// Средство для записи элемента массива. - set {
if(ok(index)) {
a[index - lowerBound] = value;
}
else throw new RangeArrayException(
"Ошибка нарушения границ диапазона.");
}}
//Метод возвращает значение true,
//если индекс в пределах диапазона,
private bool ok(int index) {
if(index >= lowerBound & index <= upperBound)
returntrue;
returnfalse;
}}
//Демонстрируем использование массива с заданным
//диапазоном изменения индекса,
classRangeArrayDemo { publicstaticvoidMain() { try {
RangeArray ra = new RangeArray( -5, 5);
RangeArrayra2 = newRangeArray(1, 10);
// Демонстрируем использование объекта -массива га.
Console.WriteLine("Длина массива га: " + ra.Length); for(int i = -5; i <= 5; i++)
ra[i] = i;
Console.Write ("Содержимое массива ra: " ) ; for(int i = -5; i <= 5; i++)
Console.Write(ra[i] + " " ) ;
Console.WriteLine("\n");
// Демонстрируем использование объекта -массива ra2.
Console.WriteLine("Длина массива ra2: " + ra2.Length); for(int i = 1; i <= 10; i++)
ra2[i] = i;
Console.Write ("Содержимое массива ra2: ") ;
for(int i = 1; i <= 10; i++) Console.Write(ra2[i] + " " ) ; Console.WriteLine("\n");
} catch (RangeArrayException exc) { Console.WriteLine(exc);
}
// Теперь демонстрируем "работу над ошибками".
Console.WriteLine(
"Сгенерируем ошибки непопадания в диапазон."); // Используем неверно заданный конструктор, try {
RangeArray ra3= new RangeArray(100, -10); // Ошибка!
} catch (RangeArrayException exc) { Console.WriteLine(exc);
}
// Используем неверно заданный индекс, try {
RangeArray ra3 = new RangeArray( -2, 2); for(int i = -2; i <= 2; i++)
гаЗ [i] = i;
Console.Write(" Содержимоемассива ra3: " ) ; for(int i = -2; i <= 10; i++) // Ошибка непопадания
// в диапазон.
Console.Write(ra3[i] + " " ) ;
} catch (RangeArrayException exc){
Console.WriteLine(exc);
}}
При выполнении этой программы получаем такие результаты:
Длина массиваra: 11
Содержимое массива ra: - 5 - 4 - 3 - 2 - 1 0 1 2 3 4 5
Длина массива ra2: 10
С о д е р ж и м о е м а с с и в а ra2 : 1 2 3 4 5 6 7 8 9 1 0
Сгенерируем ошибки непопадания в диапазон.
Нижний индекс не меньше верхнего.
Содержимое массива raЗ: - 2 - 1 0 1 2 Ошибка нарушения границ диапазона.
При возникновении ошибки нарушения границ диапазона RangeArray -объект генерирует объект типа RangeArrayException. Этот класс — производный от классаApplicationException. Класс исключений, создаваемыйпрограмм истом, обычно выводится из класса ApplicationException. Обратите внимание на то, что подобная ошибка может обнаружиться во время созданияRangeArray -объекта. Чтобы перехватывать такие исключения, объекты классаRange Array должны создаваться внутри блока try , как это показано в программе. Сиспользованием исключений для сообщений об ошибках класс RangeArray теперьнапоминает один из встроенных С# -типов и может быть полностью интегрирован вмеханизм обработки исключений любой программы.
28. Объектно оринтированное программирование
Принципы ООП проще всего понять на примере программ
моделирования. В ре альном мире каждый предмет или процесс обладает набором статических и ди намических характеристик, иными словами, свойствами и поведением. Поведение объекта зависит от его состояния и внешних воздействии. Например, объект «автомобиль» никуда не поедет, если в баке нет бензина, а если повернуть руль, изменится положение колес.
Понятие объекта в программе совпадает с обыденным смыслом этого слова: объект представляется как совокупность данных, характеризующих его состояние, и функций их обработки, моделирующих его поведение. Вызов функции на выпол нение часто называют посылкой сообщения объекту.
При создании объектно -ориентированной программы предметная область представляется в виде совокупности объектов. Выполнение программы состоит в том, что объекты обмениваются сообщениями. Это позволяет использовать при про граммировании понятия, более адекватно отражающие предметную область.
При представлении реально го объекта с помощью программного необходимо выде лить в первом его существенные особенности. Их список зависит от цели модели рования. Например, объект «крыса» с точки зрения биолога, изучающего миграции, ветеринара или, скажем, повара будет иметь соверше нно разные характеристики. Выделение существенных с той или иной точки зрения свойств называется абстрагированием. Таким образом, программный объект — это абстракция.
Важным свойством объекта является его обособленность. Детали реализации объекта, то есть внутренние структуры данных и алгоритмы их обработки, скрыты от пользователя объекта и недоступны для непреднамеренных изменений. Объект используется через его интерфейс — совокупность правил доступа.
Скрытие деталей реализации называется инкапсуляцией (от слова «капсула»). Ничего сложного в этом понятии нет: ведь и в обычной жизни мы пользуемся объектами через их интерфейсы. Сколько информации пришлось бы держать в голове, если бы для просмотра новостей надо было знать устройство телевизора!
Таким образом, объект является «черным ящиком», замкнутым по отношению к внешнему миру. Это позволяет представить программу в укрупненном виде — на уровне объектов и их взаимосвязей, а следовательно, управлять большим объ емом информации и успешно отлаживать сложные программы.
Сказанное можно сформулировать более кратко и строго: объект — это инкапсулированная абстракция с четко определенным интерфейсом.
Инкапсуляция позволяет изменить реализацию объекта без модификации основ ной части программы, если его интерфейс ос тался прежним. Простота модифи кации является очень важным критерием качества программы, ведь любой про граммный продукт в течение своего жизненного цикла претерпевает множество изменений и дополнений.
Кроме того, инкапсуляция позволяет использовать объект в другом окружении и быть уверенным, что он не испортит не принадлежащие ему области памяти, а также создавать библиотеки объектов для применения во многих программах.
Каждый год в мире пишется огромное количество новых программ, и важнейшее значение прио бретает возможность многократного использования кода. Преиму щество объектно -ориентированного программирования состоит в том, что для объекта можно определить наследников, корректирующих или дополняющих его поведение. При этом нет необходимости не только п овторять исходный код родительского объекта, но даже иметь к нему доступ.
Наследование является мощнейшим инструментом ООП и применяется для сле дующих взаимосвязанных целей:
•исключения из программы повторяющихся фрагментов кода;
•упрощения модификации программы;
•упрощения создания новых программ на основе существующих.
Кроме того, только благодаря наследованию появляется возможность использо вать объекты, исходный код которых недоступен,
но в которые требуется внести изменения.
Наследование позволяет создав ать иерархии объектов. Иерархия представляется в виде дерева, в котором более общие объекты располагаются ближе к корню, а бо лее специализированные — на ветвях и листьях. Наследование облегчает исполь зование библиотек объектов, поскольку программист може т взять за основу объек ты, разработанные кем -то другим, и создать наследников с требуемыми свойствами.
Объект, на основании которого строится новый объект, называется родительским объектом, объектом -предком, базовым классом, или суперклассом, а унаследо ванный от него объект — потомком, подклассом, или производным классом.
ООП позволяет писать гибкие, расширяемые и читабельные программы. Во мно гом это обеспечивается благодаря полиморфизму, под которым понимается воз можность во время выполнения программы с помощью одного и того же имени выполнять разные действия или обращаться к объектам разного типа. Чаще все го понятие полиморфизма связывают с механизмом виртуальных методов.
Подводя итог сказанному, сформулирую достоинства ООП.
•использование при программировании понятий, близких к предметной области;
•возможность успешно управлять большими объемами исходного кода благо даря инкапсуляции, то есть скрытию деталей реализации объектов и упроще нию структуры программы;
•возможность многократного использо вания кода за счет наследования;
•сравнительно простая возможность модификации программ;
•возможность создания и использования библиотек объектов.
Эти преимущества особенно явно проявляются при разработке
программ большого объема и классов программ. Однако н ичто не дается даром: создание объектно -ориентированной программы представляет собой весьма непростую задачу, по скольку требует разработки иерархии объектов, а плохо спроектированная иерар хия может свести к нулю все преимущества объектно -ориентированного подхода.
Кроме того, идеи ООП не просты для понимания и в особенности для практиче ского применения. Чтобы эффективно использовать готовые объекты из биб лиотек, необходимо освоить большой объем достаточно сложной информации. Неграмотное же применение ОО П способно привести к созданию излишне слож ных программ, которые невозможно отлаживать и усовершенствовать
29. Описание класса
содержит ключевое слово class, за которым следует его имя,а далее в фигурных скобках - тело класса, то есть список его элементов. Кроме того, для класса можно задать его базовые классы (предки) и ряд необязательных ат рибутов и спецификаторов, определяющих различные характеристики класса:
[ атрибуты ] [ спецификаторы ] classимя-класса [ : предки ] тело-класса
Как видите, обязательными являются только ключевое слово class, а также имя и тело класса. Имя класса задается программистом по общим правилам С#. Тело класса— это список описаний его элементов, заключенный в фигурные скобки. Список может быт ь пустым, если класс не содержит ни одного элемента. Таким образом, простейшее описание класса может выглядеть так:
classDemo {}
Необязательные атрибуты задают дополнительную информацию о классе.
Спецификаторы определяют свойства класса, а также доступность класса для других элементов программы. Возможные значения спецификаторов перечисле ны в табл. 1.1. Класс можно описывать непосредственно внутри пространства имен или внутри другого класса. В последнем случае класс называется вложенным. В зависимости от
