
Ответы_ТП
.pdfint i;
Console.WriteLine("Удаление пробелов."); for(i=0; i < a.Length; i++)
if(a[i] != ‘ ’) temp += a[i]; a = temp;
}
// Метод реверсирует строку, static void reverse(ref string a) { string temp = "";
int i, j;
Console.WriteLine("Реверсирование строки."); for(j=0, i=a.Length -l; i >= 0; i—, j++)
temp += a[i]; a = temp;
}
public static void Main() {
// Создаем экземпляры делегатов. strMod strOp;
strMod replaceSp = new strMod(replaceSpaces); strMod removeSp = new strMod(removeSpaces); strMod reverseStr = new strMod(reverse); stringstr = "Это простой тест.";
// Организация многоадресатной передачи. strOp = replaceSp;
strOp += reverseStr;
// Вызов делегата с многоадресатной передачей. strOp(refstr);
Console.WriteLine ("Результирующая строка: " + str);
Console.WriteLine();
//Удаляем метод замены пробелов и
//добавляем метод их удаления.
strOp -= replaceSp; strOp += removeSp;
str = "Это простой тест."; // Восстановление
//исходной строки.
//Вызов делегата с многоадресатной передачей.
strOp(ref str);
Console.WriteLine("Результирующая строка: " + str);
Console.WriteLine();
}}
Вот как выглядят результаты выполнения этой программы:
Замена пробелов дефисами.
Реверсирование строки.
Результирующая строка: .тсет-йотсорп-отЭ Реверсирование строки.
Удаление пробелов.
Результирующая строка: .тсетйотсорпотЭ
В методе Main() создаются четыре экземпляра делегата. Первый, strOp, имеет null-значение. Три других ссылаются на методы модификации строк. Затем организует ся делегат для многоадресатной передачи, который вызывает методы removeSpaces()и reverse(). Это достигается благодаря следующим строкам программы:
strOp= repiaceSp ;
strOp += reverseStr;
Сначала делегату strOp присваивается ссылка replaceSp. Затем, с помощью оператора "+=", в цепочку вызовов добавляется ссылка reverseStr. При вызове делегата strOp в этом случае вызываются оба метода, заменяя пробелы дефисами и реверсируястроку.
Затем при выполнении строки программы
strOp -== replaceSp;
из цепочки вызовов удаляется ссылка replaceSp, а с помощью строкиstrOp += removeSp; в цепочку вызовов добавляется ссылка removeSp.
Затем делегат StrOp вызывается снова. На этот раз из исходной строки удаляютсяпробелы, после чего она реверсируется.
Цепочки вызовов, организованные с помощью делегата, — мощный механизм, который позволяет определять набор методов, выполняемых "единым блоком". Цепочки делегатов имеют особое значение для событий.
Все делегаты представляют собой классы, которые неявным образом выводятся из класса System.Delegate . Обычно его члены не используются напрямую. Все же в некоторых ситуациях его члены могут оказаться весьма полезными.
Делегаты используются по двум основным причинам.
Во-первых, делегаты обеспечивают поддержку функциониро вания
событий.
Во-вторых, делегаты позволяют во время выполнения программы выполнить метод, который точно не известен в период компиляции. Эта возможность особенно полезна, когда нужно создать оболочку, к которой могли бы подключаться программныекомпоненты . Например, представьте графическую программу (наподобие стандартнойутилиты Windows Paint). Используя делегат, можно было бы разрешить пользователюподключать специальные цветные светофильтры или анализаторы изображений. Более того, пользователь мог бы созд авать "свои" последовательности этих фильтровили анализаторов.
25. Наследование интерфейсов
Один интерфейс может унаследовать "богатство" другого. Синтаксис этого механизма аналогичен синтаксису, используемому для наследования классов. Если класс реализуе т интерфейс, который наследует другой интерфейс, этот класс должен обеспечить способы реализации для всех членов, определенных внутри цепочки наследования интерфейсов. Рассмотрим такой пример:
/ / Один интерфейс может наследовать другой.
usingSystem;
publicinterfaceA {
voidmeth1 () ;
void meth2();
}
// Интерфейс В теперь включает методы methl() и meth2(),
// а также добавляет метод meth3().
public interface В : A {
void meth3();
}
//Этот класс должен реализовать все методы
//интерфейсов А и В.
class MyClass : В { public void meth1() {
Console. WriteLine (" Реализацияметода meth1().");
}
public void meth2() {
Console.WriteLine(" Реализацияметода meth2().");
}
public void meth3() {
Console.WriteLine(" Реализацияметода meth3().");
}}
class IFExtend {
public static void Main() { y MyClass ob = new MyClass(); ob.meth1();
ob.meth2(); ob.meth3();
}}
26. Наследование как фундаментальный принцип ООП
Наследование — один из трех фундаментальных принципов объектно -ориентированного программирования, именно благодаря ему
возможно |
создание |
иерархических |
классификаций. |
Используя |
|||
наследование, |
создают |
общийкласс, |
который |
определяет |
характеристики, присущие множеству связанных элементов. Этот класс затем может быть унаследован другими, узкоспециализированнымиклассами с доб авлением в каждый из них своих, уникальных особенностей.
В языке С# класс, который наследуется, называется базовым. Класс, который наследует базовый класс, называется производным. Следовательно, производный класс —это специализированная версия базового класса. В производный класс, наследующийвсе переменные, методы, свойства, операторы и индексаторы, определенные в базовом классе, могут быть добавлены уникальные элементы.
5.1.1 Основы наследования
С# поддерживает наследование, позволяя в объявление класса встраивать другойкласс. Это реализуется посредством задания базового класса при объявлении производного. Рассмотрим класс TwoDShape, в котором определяются атрибуты "обобщенной" двумерной геометрической фигуры (например,квадрата, прямоугольника, треугольника и т.д.).
Класс TwoDShape можно использовать в качестве базового (т.е. как стартовую площадку) для классов, которые описывают специфические типы двумерных объектов. Например, класс TwoDShape используется для выведения класса Triangle.
// Простая иерархия классов.
usingSystem;
// Классдвумерныхобъектов ,
classTwoDShape {
public double width;
public double height;
public void showDim() {
Console.WriteLine(" Ширинаивысотаравны " + width + " и " + height);
}}
// Класс Triangle выводится из класса TwoDShape. class Triangle : TwoDShape {
public string style; // Типтреугольника .
// Метод возвращает площадь треугольника, publicdoublearea () {
returnwidth * height / 2;
}
// Отображаем тип треугольника, public void showStyle() {
Console.WriteLine(" Треугольник " + style);
}}
class Shapes {
public static void Main() { Triangle t1 = newTriangle(); Triangle t2 = new Triangle() ; t1.width = 4.0;
t1.height- 4.0;
t1.style = "равнобедренный ";
t2.width = 8.0;
t2.height = 12.0;
t2.style = " прямоугольный";
Console.WriteLine(" Информацияо t1 : " ) ;
t1.showStyle();
t1.showDim();
Console.WriteLine (" Площадьравна " + t1.area());
Console.WriteLine();
Console.WriteLine(" Информацияо t2: " ) ;
t2. showStyle() ;
t2.showDim();
Console.WriteLine(" Площадьравна " + t2.area());
}}
Вот результаты работы этой программы.
Информация о tl:
Треугольник равнобедренный
Ширина и высота равны 4 и 4
Площадь равна 8
Информация о t2:
Треугольник прямоугольный
Ширина и высота равны 8 и 12
Площадь равна 4
В классе Triangle создается специфический тип объекта класса TwoDShape, в данном случае треугольник. Класс Triangle содержит все элементы класса TwoDShape и, кроме того, поле style, метод area() и метод showStyle(). В переменной style хранится описание типа треугольника, метод area () вычисляет и возвращает его площадь, а

метод showstyle() отображает данные о типе треугольника.
Если один класс наследует другой, то имя базового класса указывается после имени производного, причем имена классов разделяются двоеточием. ВС# синтаксис наследования класса очень прост для запоминания и использования.
Поскольку класс Triangle включает все члены базового класса, TwoDShape, он может обращаться к членам width и height внутри метода агеа(). Кроме того, внутри метода Main() объекты t1 и t2 могут прямо ссылаться на члены width и height, как если бы они были частью класса Triangle. Включение класса TwoDShape в класс Triangle схематически показано на рис. 2.
Рисунок 2
Общая форма объявления класса, который наследует базовый класс, имеет такой вид:
class имя__производного_класса : имя_базового_класса {
// тело класса
}
Для создаваемого производного класса можно указать только один базовый класс.
ВС# (в отличие от C++) не поддерживается наследование
нескольких базовых классов в одном пр оизводном классе.
Основное достоинство наследования состоит в том, что, создав базовый класс, который определяет общие атрибуты для множества объектов, его можно использоватьдля создания любого числа более специализированных производных классов. В каждом п роизводном классе можно затем точно " настроить" собственную классификацию.
Вот, например, как из базового класса TwoDShape можно вывести производный класс, который инкапсулирует прямоугольники:
//Класс прямоугольников Rectangle, производный
//от класса TwoDShape.
classRectangle :TwoDShape {
//Метод возвращает значение true, если
//прямоугольник является квадратом,
publicboolisSquare () {
if(width == height) returntrue;
returnfalse;
}
// Метод возвращает значение площади прямоугольника,
public double area() {
return width * height;
}}
Класс Rectangle включает класс TwoDShape и добавляет метод isSquare(), который определяет, является ли прямоугольник квадратом, и метод area(), вычисляющий площадь прямоугольника.
27. Наследование классов исключений
В |
С# |
имеется |
возможность |
обрабатывать |
исключения, |