Разработаны Адаевым Р. Б. и Данилюком Д. Э

Ответы к экзамену по ООП Кузьминой Т. М.

Разработаны Адаевым Р. Б. и Данилюком Д. Э.

Содержание

1.Среда визуального программирования SharpDevelop. Создание и сохранение проекта. Форма. Визуальные компоненты. Окно свойств. Создание обработчика события. 4

2.Компонент Button. Для чего он нужен? Программное и пользовательское имена компонента Button. Создание обработчика события. Примеры. 5

3.Визуальные компоненты. Какие свойства определяют местоположения и размеры визуальных компонентов? Программное и пользовательское имена компонентов. Как изменить свойства компонентов? Примеры. 5

4.Ввод/вывод информации. Компонент TextBox. Класс Convert. Метод ToString(). Примеры 6

5.Компоненты CheckBox и RadioButton. 6

6. Преобразование числовых типов языка C#. Преобразование числовых типов в строковый тип и значение типа string в числовой тип. Класс Convert. Метод ToString(). Примеры использования. 7

7. Класс-ссылочный тип. Описание класса и создание объекта. Операция доступа к членам класса. Примеры. 7

8.Конструктор класса. Особенности класса. Примеры. 8

9.Уровни доступа к членам класса. Работа с закрытыми членами класса. Примеры. 9

10.Статические члены класса. Статический конструктор класса. Пример класса, содержащего статические члены. 10

11.Структурные типы. Сравнение структурных и ссылочных типов. 11

12.Сравнение работы оператора присваивания со структурными и со ссылочными типами. 12

13.Передача параметров методу (без использования модификаторов). 12

14.Создание метода, имеющего произвольное число параметров. 13

15. Передача параметров методу. Модификаторы ref и out. Примеры.. 13

16. Одномерные массивы. Массивы ссылочных типов. Примеры. 14

17.Многомерные массивы, прямоугольные и зубчатые. Примеры. 15

18. Сортировка элементов массива. Интерфейс IComparable, метод CompareTo. 16

19. Перегрузка функций (методов). Примеры. 17

20. Перегрузка операторов. Примеры. 17

21.Исключительные ситуации. Обработка исключений. Блоки try-catch. Примеры. 19

22.Исключительные ситуации. Обработка исключений. Блоки try-catch-finally. 20

23.Исключительные ситуации. Обработка исключений. Создание собственного исключения 20

24.Наследование классов. Иерархии классов. Примеры. 20

25.Виртуальные и невиртуальные методы. Ссылки базовых классов. Примеры. 22

26.Класс object. Переопределение метода ToString(). Примеры. 24

27. Преобразование типов. Операторы is и as. 25

28. Графики на C#. Создание рисунка во время работы приложения. Класс Graphics. Система координат. Вывод контурных примитивов на экран. 25

29. Свойства. Примеры. 25

30.Абстрактные методы, абстрактные классы.. 26

31.Интерфейсы.Их основное назначение. Что означает фраза «класс А поддерживает интерфейс I»?. 27

32.Интерфейсы, ссылки на интерфейсы. 28

33.Оформление абстрактных методов в абстрактном классе и в интерфейсе. Примеры. 28

34.Теория ООП: инкапсуляция. 28

35.Теория ООП: наследование и агрегация. 30

36. Теория ООП сравнение обьектов и модулей. 31

37. Списки. Проблемы, возникающие при реализации списков массивами. Решение этих проблем в ООП. 31

38. Обобщенные классы. Класс List<T>. Пример. 32

39. Обобщенные классы. Ограничение на базовый класс. Пример. 33

40. Обобщенные классы. Ограничение на интерфейс. Пример. 34

41. Ограничения new, class, struct. Пример. 34

42. Делегаты. Примеры. 36

43.События. Использование делегатов. 37

44.События. Классы-издателя и классы-подписчики.Примеры. 38

45. Лямбда-выражения. Примеры. 40

47. Создание диалогового окна в проекте Передача информации из диалоговой формы в основную форму. 41


Компонент Button. Для чего он нужен? Программное и пользовательское имена компонента Button. Создание обработчика события. Примеры.

Компонент Button реализует стандартн.кнопку Windows. В основном он использ-ся д/инициирования каких-либо событий. Окно св-в: осн.св-во кнопки – Caption (Надпись), знач-ие кот.должно коротко и четко пояснять назнач-ие кнопки. Св-во Color (Цвет) определяет цвет фона компонента. Св-во Height опред.высоту компонента. Width - ширина, и др. Программн. имя компонента Button указывается в св-ве Name, пользовательск.имя - в св-ве Text.

Свойство Text – надпись на компоненте, оно имеет тип string, Данное свойство также можно изменить. При задании значения свойства Text можно использовать русские буквы и другие символы, запрещенные при определении идентификаторов. 

Свойства Left, Top, задают координаты левого верхнего угла кнопки в системе координат компонента–контейнера. Компонент-контейнер – это компонент, на котором располагается кнопка. Каждый визуальный компонент имеет свою систему координат, в этой системе координат точка (0,0) располагается в верхнем левом углу, ось Х направлена слева на право, ось У сверху вниз

Созд-ие обработчика событий:поместим кнопку, нажмем 2раза, Будет создан обработчик событий Click. Пример: код отображает сообщение при нажатии Кнопки1

private void Button1Click (object sender, System.EventArgs e)

{ MessageBox.Show("Привет!"); }

Визуальные компоненты. Какие свойства определяют местоположения и размеры визуальных компонентов? Программное и пользовательское имена компонентов. Как изменить свойства компонентов? Примеры.

Слева от дизайнера формы располагается палитра визуальных компонентов (Button, Check Box, Combo Box, Label, RudioButton, TextBox, CheckedListBox, DateTimePicker, DomainUpDown, FlowLayoutPanel, GroupBox, HScrollBar, LinkLabel, ListBox, ListView,  MaskedTextBox, MounthCalendar, NimericUpDown, Panel, PictureBox, ProgressBar,  PropertyGrid, RichTextBox, SplitContainer, TabControl, TableLayoutPanel, ToolTip, TrackBar, TreeView, VScrollBar, WebBrowser, ContextMenuStrip, MenuStrip, StatusStrip, ToolStrip, ToolStripContainer, ColorDialog, ErrorProvider, FontDialog, FolderBrowserDialog, ImageList, HelpProvider, OpenFileDialog, SaveFileDialog, Timer).

Местоположение компонентов опред-ет св-во "Location", в нем задаются значения X (отступ слева Left) и Y (отступ сверху Top). Размеры компонентов отпред-ет св-во "Size", в кот.задаются знач-ия Width (длина) и Height (высота).

Программное имя компонента это компонента, прописываемое в программе, а пользовательское это то, которое расположена на компоненте, его можно визуально увидеит.

Для изменения положения кнопки или любого другого компонента на форме следующие команды:

button1. Left= button1. Left+10;

При обращении к свойствам формы в обработчиках событий этой формы можно использовать служебное слово this. Например, команды this. Width, this. Height будут обращениями, соответственно, к ширине и высоте текущей формы. Команда this. Height =450; изменит высоту формы, а строка

if (this. Height < button1. Top+25) button1. Top=100;

переместит кнопку button1, если она находится на нижнем краю формы.

Мы можем делать радиокнопки и другие ВК видимыми и невидимыми, цветными, доступными и недоступными.

Ввод/вывод информации. Компонент TextBox. Класс Convert. Метод ToString(). Примеры

Вводить и выводить инф-ию можно несколькими способами. Для ввода всегда используют компонент TextBox, для вывода используют в основном TextBox или Label. Компонент TextBox часто используется д/того, чтобы позволить пользователю ввести текстовые данные д/обработки. Этот компонент является редактором текста. Значение его свойства Text выводится на экран и может быть изменено пользователем с помощью различных средств редактирования.

Измененное пользователем значение свойства Text, имеющего тип string, может быть считано и использовано в работе приложения. Например, строка

int i= Convert.ToInt32(textBox1.Text);

позволяет записать значение свойства Text в переменную i, предварительно выполнив преобразование типов. Многие функции преобразования типов включены в библиотечный класс Convert, в нашем примере использован метод ToInt32.

Значения, вводимые в поле, хранятся в свойстве Text. Эти значения принимают тип String. ( Пр.: textbox1.Text = "Привет!"; ).

Класс Convert преобразует знач-ия между типами данных.( Пр: int a = 6; string b = "Gg"; b = Convert.ToString(a); Но a = Convert.ToInt32(b); невозможно перевести, т.к. в переменную b присвоен текст(Gg). Но если бы b = "123"; тогда бы было можно перевести так как текстом является целое число.).

Все встроенные типы данных C# предоставляют метод ToString(), преобразующий знач-ие в строку. Этот метод может быть использован д/преобразования числовых знач-ий в строки.

 (Пр.: Создается строка "Сообщение" путем объединения задаваемой строки и преобразованного в строку знач-ия целочисленной переменной "Год": int Год = 1999; string Сообщение = "Я родился в " + Год.ToString(); )

       Пример: строка textBox1.Text = Convert.ToString(i) позволит вывести на экран значение переменной i.

Свойство ReadOnly позволяет запретить или разрешить изменение значения свойства Text пользователем. Это свойство имеет логический тип. Если значение свойства ReadOnly – true (истина), то свойство Text компонента TextBox во время работы приложения доступно только для чтения, в этом случае компонент TextBox можно использовать только для вывода информации. Если свойство ReadOnly равно false, то компонент Edit можно использовать и для ввода и для вывода информации.

Рассмотрим еще два свойства Enable, Visible. Оба этих свойства имеют логический тип. Первое определяет, доступен ли компонент, т.е. реагирует ли он на события, связанные с мышью, клавиатурой и таймером. Недоступный компонент отображается на форме бледным цветом. Второе свойство задаёт видимость или невидимость компонента.

Также вопрос 4.

Класс-ссылочный тип. Описание класса и создание объекта. Операция доступа к членам класса. Примеры.

Класс в C# - это ссылочный тип. Класс имеет описание, кот.должно быть в отдельном файле. Описание класса начинается со слова "class". Перед этим словом может быть указан уровень доступа класса. Далее идет имя класса: class A {... Членами типов могут быть поля, предназначенные для хранения данных, и методы (ф-ии, члены класса), события, св-ва, события и вложенные типы.

Например:

class Myclass {

public int i; /* слово public обозначает, что данный член класса является общедоступным*/

public float x;

public float f()

{return i*y;}}

Модификаторов доступа для классов есть два:

-      public – доступ к классу возможен из любого места приложения,

-      internal – доступ к классу возможен только из сборки, в которой он объявлен.

Во всех объектно-ориентированных языках четко различаются понятия «класс» и «объект». Класс – это определяемый пользователем тип данных, его можно представить себе как чертеж, по которому будут строиться сами данные, т.е. объекты (экземпляры) класса.

Поле или член-данное – это переменная, объявленная внутри класса. Метод или функция-член – это функция, объявленная внутри класса.

Д/объявления объекта используется след.конструкция: <имя класса> имя переменной = new <имя класса>(); Именем объекта будет ссылка на этот объект. Пр.: Animals cat = new Animals(); Эта строка объявления выполняет 3 функции. Во-1ых, объявляется переменная cat, относящаяся к типу класса Animals. Сама эта переменная не является объектом, а лишь переменной, кот.может ссылаться на объект. Во-2ых, создается конкретная, физическая, копия объекта. Это делается с помощью оператора new. И наконец, переменной cat присваивается ссылка на данный объект. Таким образом, после выполнения строки объявленная переменная cat ссылается на объект типа Animals. Точка - это операция доступа к членам класса (пр.: cat.x = ...)

Ключевое слово new означает, что среде выполнения следует вызвать конструктор класса и выделить необходимое количество оперативной памяти под экземпляр класса. Поскольку класс относится к ссылочному типу, то выделении памяти производится из «кучи», находящейся в распоряжении среды выполнения .NET.

Команда newА(), создаст объект, т.е. среда .NET выделит под этот объект память, но такой объект не будет иметь имени и с ним невозможно будет работать. Для того, что бы дать объекту имя нужно создать ссылку. Команда А а; создает ссылку типа А. Ссылка похожа на указатель языка Си++, но она, в отличии от указателя, не может содержать произвольный адрес. При выполнении команды А а; создается ссылка, со значением null, т.е. она содержит некоторый стандартный адрес. При выполнении команды а= newА(); адрес созданного объекта класса записывается в ссылку а и а становится именем созданного объекта. Теперь мы уже можем работать с созданным объектом

Рассмотрим еще один пример:

Myclass c=new Myclass();

Myclass d;

d=c;

В этом примере создан один объект и две ссылки на него.

Пример:

c.x=7; //полю х объекта с присвоено значение 7.

d.i=6; //полю i объекта d присвоено значение 6.

Конструктор класса. Особенности класса. Примеры.

Объект превращается в «мусор», если он теряет свое имя, например, из-за того, что ссылка стала указывать на другой объект. Значит, время жизни зависит, прежде всего, от ссылки-имени. Если ссылка объявлена, как локальная переменная, и другого имени объект не приобрел, то он будет локальным.

Например, если команда A a=new A(); записана в обработчике события, то объект а, будет жить, только во время работы этого обработчика.

Если продолжить рассмотрение объектов класса, созданных профессионалами, таких, как кнопка Button, то мы увидим, что при создании этих объектов используются не нулевые значения полей, поскольку кнопки, имеют определенные размеры, цвет и т.д., задается местоположение. Все это позволяют сделать конструкторы классов.

Конструктор класса – это метод класса, который предназначен для создания объектов класса и инициализации их.

Конструктор обладает следующими свойствами:

1.Имя конструктора совпадает с именем класса.

2.Конструктор не имеет возвращаемого значения, даже типа void

3.Класс может содержать несколько конструкторов, отличающихся либо количеством, либо типами параметров, либо и тем и другим вместе.

4.Конструктор без параметров называется конструктором по умолчанию.

5.Если ни один конструктор не был написан программистом, то конструктор по умолчанию генерируется компилятором.

6.Если в классе объявлен хотя бы один конструктор, то компилятор не создает своего.

7.В C# , в отличие от многих других языков, любой конструктор, если не указано иное, обнуляет значения полей.

8.Конструктор не может быть вызван явно, он вызывается автоматически при создании экземпляров класса.

Рассмотрим пример. Определим в классе А два конструктора.

class A { public int x,y;

public int f() {return x*y;}

public A() { x=1; y=2; }

public A (int xx, int yy) { x=xx; y=yy;} }

При выполнении команды A a=new A(); для создания объекта класса используется конструктор без параметров. Полям объекта а будут присвоены, соответственно, значения 1 и 2.

Если при создании объекта требуется использовать конструктор с параметрами, то в операторе new после имени класса в круглых скобках указываются значения параметров, например, A obj1=new A(6,13);

А команда A obj22=new A(3); вызовет ошибку, потому что класс А не содержит конструктора с одним параметром, которому можно было бы присвоить значение 3.

В языке С# существует упрощенная форма написания конструктора: при описании полей класса можно написать инициализирующие выражения.

Пример. class В { public int i=10;}

Все строки, содержащие инициализирующие выражения, включаются в начало всех конструкторов. В данном примере строка i=10; будет включена в конструктор, определяемый компилятором.

Замечание. При создании объекта класса на языке C#, поля объекта, если им не заданы определенные значения, обнуляются.

Пример. В конструкторе генерация случайных чисел

public class Vector //Описание класса «Элемент»

{int name;

public Vector()

       {

              Random rnd=new Random();

                   name=rnd.Next(1,100);

       }

public string getName()

       {

                              return name.ToString();

       }

                   }

Уровни доступа к членам класса. Работа с закрытыми членами класса. Примеры.

ООП5. В С# имеется пять спецификаторов доступа: public, private, protected, internal, protected internal . Значения спецификаторов доступа следующие:

-public - член класса может быть использован любым методом;

-private - член класса может быть использован только методом того же класса,

-protected- член класса может быть использован только либо методом того же класса, либо методом производного класса;

-internal- член класса может быть использован только методом из той же сборки;

-protected internal- член класса может быть использован только либо методом из той же сборки или методом производного класса из любой сборки.

Если класс содержит закрытые члены (закрытые для вн.доступа), то должны быть открыты методы, которые позволяют работать с этими членами класса.

Пример: Предположим нам надо создать класс для работы с окружностью, в этом классе у нас будет поле, содержащее радиус. Значение радиуса должно быть числом неотрицательным. Конечно, при каждом вводе мы можем проверять это значение, именно так поступают в процедурном программировании. Но в ООП задачу можно решить другим способом. Проверка останется, но она будет реализована в классе.

Для этого определим уровень доступа к полю на private или protected, т.е. сделаем его закрытым от обращений извне. В этом случае нужно будет написать два открытых метода для того, что бы вводить и       выводить информацию.

class Circle{

private int R;

public int get_R(){return x;}

public bool set_R(int rr)

{ if(rr < 0) return true; r=rr;

return false ;}}

В поле r класса Circle уже нельзя ввести отрицательного значения, метод set_R контролирует ввод, причем он возвращает информацию о том, была ли допущена ошибка. Можно например, сделать, чтобы при отрицательном вводе радиус становился равным 1.

Пример :

class Rectangle

{

   private double dlina, shirina;

   public double get_X(){return dlina;}

   public void set_X(double xx){

   if (xx>7 & xx<10) dlina=xx;

  else {MessageBox.Show ("Неправильный диапазон данных");}

   }

                  

   public double get_Y(){return shirina;}

   public void set_Y(double yy){

   if(yy > 0) shirina=yy;

   else {MessageBox.Show (" Неправильный диапазон данных ");}

   }

Статические члены класса. Статический конструктор класса. Пример класса, содержащего статические члены.

ООП8. Иногда возникает необходимость, того, что бы какое-то поле было общим для всех объектов одного типа. В этом случае используются статические поля. Статическое поле описывается с использованием слова static. Статическим может быть и метод.

Обратиться к статическому члену класса можно через имя класса. Например. В команде int i= Convert.ToInt32(textBox1.Text); используется библиотечный класс Convert, в котором собраны многие функции преобразования типов, оформленные, как статические методы. Convert.ToInt32 – это вызов статического метода, выполняющего перевод в тип int.

                Со статич.членами класса могут работать нестатич.методы класса, но также придуманы статич.методы. Статический метод может непосредственно вызывать только статические методы и оперировать непосредственно только статическими полями. Чтобы стат.метод обратился к нестатич.полю, надо создать внутри этого метода или получать извне объект и работать с полями объекта.

                Рассмотрим пример, предположим нам нужно знать сколько объектов определенного класса создано. Назовем этот класс буквой D.

class D{

private static int n;

public D(){n++;}

public static int get_N()

{return n;}}

В классе D есть статические поле и метод. Со статическим полем может работать и нестатический метод, в данном случае с полем работает конструктор. При каждом создании объекта конструктор вызывается, и, следовательно, значение n увеличивается на единицу. Для того, что бы узнать, сколько объектов класса D создано нужно вызвать метод get_N(), т.е. написать команду D. get_N();

D ob1= new D ();

D ob2=new D ();

D ob3=new D();

I=B.get_N; //I=3

Передача параметров методу. Модификаторы ref и out. Примеры

Ref .

Модификатор ref предназначен для указания того, что параметр метода должен передаваться по ссылке а не по значению. Другими словами, если у методу нужно принудительно передать аргумент по ссылке, то при объявлении метода перед соответствующим формальным параметром нужно указать модификатор ref.

Пример 1. Реализация метода, который умножает число на 5. Число есть входным параметром метода. Метод получает значение числа, умножает его на 5 и возвращает с помощью модификатора ref. То есть, метод увеличивает в 5 раз значение аргумента.

// метод, который увеличивает параметр x в 5 раз

public void Mult5(ref int x)

{

x = x * 5;

}

Вызов метода Mult5() из другого программного кода

int d = 10;qe.Mult5(ref d); // d = 10*5 = 50

После вызова, значение переменной d становится равным 50. Согласно синтаксису C#, перед вызовом переменной d нужно ставить модификатор параметра ref.

Out .

Модификатор параметра out используется, если необходимо выполнение двух условий:

· методу не нужно передавать значение;

· метод обязательно должен возвращать значение с помощью параметра.

Модификатор out для параметра с именем param типа type указывается в начале его объявления

Пример 1. Разработать метод, который возвращает число Авогадро. Число Авогадро задается параметром метода.
Текст метода:

// число Авогадро

void GetAvogadro(out double Avg)

{

Avg = 6.022140857e23;

}

Вызов метода из другого программного кода

// вызов метода GetAvogadro() из другого метода

double Avg;

GetAvogadro(out Avg); // указание модификатора out - обязательно

// Avg = 6.022140857E+23

Как видно из вышеприведенного кода, при вызове метода, который содержит out-параметр, обязательно нужно указывать модификатор out

GetAvogadro(out Avg);

Одномерные массивы. Массивы ссылочных типов. Примеры.

Массивом называют упорядоченную совокупность элементов одного типа. Каждый элемент массива имеет один или несколько индексов. Индексы задаются целыми числами. Число индексов определяет размерность массива. Если число элементов массива известно в момент его объявления и ему может быть выделена память ещё на этапе трансляции, то такие массивы называются статическими. Если же число элементов массива определяется во время работы программы, то такой массив называют динамическим. Массиву, как правило, выделяется непрерывная область памяти.

Массивы могут быть одномерными и многомерными. Как все в мире C#, массивы это объекты классов. Место для них выделяется в «куче», работа с ними происходит по ссылке.

Массив описывается следующим образом: <тип> [] <имя_массива>;

Имя массива это ссылка, если массив не инициализируется при объявлении, то создается он оператором new. Рассмотрим пример.

int [] mas1; mas1=new int[10];

Число элементов массива задается в момент его создания. В нашем примере мы создали статический массив, но можно было поступить следующим образом:

int n=Convert.ToInt32(textBox1.Text);

int [] mas2=new int[n];

В    этом случае, число элементов массива задает пользователем во время работы программы, т.е. создается динамический массив.

Статический массив может быть создан с помощь инициализирующего значения, например: int [] mas3={1,4.-5,9,-4}.

При создании массива с помощью оператора new, элементы обнуляются. Нумерация элементов массива начинается с 0, т.е. первый элемент массива будет иметь номер 0.

Работа с массивом происходим стандартным образом:

mas1[0]=6;//первому элементу массива mas1 присвоено значение 6 mas2[0]=3;//элементу под номером 0, массива mas2 присвоено значение 3 mas1[1]=mas1[0]+mas3[0]; //элементу под номером 1, массива mas1 //присвоена сумма значений первых элементов массивов mas1, mas3.

Поскольку в C# массив – объект некоторого класса, можно использовать, методы и свойства этого класса. Так, например, Length – свойство для чтения, возвращающее число элементов массива, если x= mas3.Length; то х получит значение 5.

Массивы ссылочных типов .

class A { public int x,y;

           public int f() {return x+y;}

public A() { x=1; y=2; }

   public A (int xx, int yy) { x=xx; y=yy;} }

Если строить массив объектов некоторого класса А, то по команде A[] mas4=new A[7]; создается не сам массив, а массив ссылок. Каждый элемент массива должен быть создан персонально, например, в цикле

for(int i=0;i<7;i++) mas4[i]=new A();

Возможно и такое решение:

Point [] p ={ new Point (10,20), new Point (40,20), new Point (30,30), new Point (40,60)}; p – это массив точек – объектов класса Point, он инициализирован при объявлении.

A[] mas5={ new A(),new A(3,4),new A(1,2),new A(3,5)}

Элементы массива – это объекты класса. Каждый элемент массива имеет свои поля, определенные в классе А, и для каждого элемента можно вызвать метод f, так же определенный в классе А.

Многомерные массивы, прямоугольные и зубчатые. Примеры.

ООП48.

Многомерные массивы бывают прямоугольные и ступенчатые

(зубчатые).

 Определение прямоугольного n-мерного массива выглядит следующим образом:

<тип>[,,,,,] имя_массива;

В квадратных скобках n-1 запятая. При объявлении ступенчатого n-мерного массива запятые не пишутся, но пишется n пар квадратных скобок. Самыми распространенными среди многомерных массивов являются двумерные.

Команда int [,] mas21=new int[3,4]; определяет прямоугольный массив, содержащий 3 строки и 4 столбца. Прямоугольные массивы удобно представлять в виде таблицы (матрицы).

mas 21[0,0]=25; mas 21[1,0]=-3; mas 21[0,1]= mas 21[0,0]+ mas 21[1,0];

Пример: создать трехмерный массив, содержащий 2 строки, 3 столбца и 4 слоя.

int [,,] mas = new int [2,3,4]

Запятых на единицу меньше, чем размерностей массива.

При создании массивов ссылочных типов, как правило, сначала создается массив ссылок, а затем уже сами элементы массива. Например,

A [,] mas22=new A[4,5]; //создается массив ссылок

for(int i=0;i<4;i++)

for(int j=0;j<5;j++)

mas22[i,j]=new A(); // создаются сами элементы массива.

Если класс А имеет общедоступное поле х, то по команде mas22[0,0].x=8; в поле х элемента mas22[0,0] запишется число 8.

В момент описания массива можно создать его полностью, например:

Point[,] p2={{new Point(10,20), new Point(40,20)},

{ new Point (30,30), new Point (40,60)}};

Создан р2 массив точек, содержащий две строки и два столбца.

В ступенчатых массивах сначала определяется число строк, а затем указывается длина каждой строки. Например:

int[][] mas23=new int[3][];// определяем число строк ступенчатого массива;

mas23[0]=new int[2]; // определяем длину первой строки

mas23[1]=new int[6]; // определяем длину второй строки

mas23[2]=new int[3]; // определяем длину третьей строки

mas23[0][0]=8; // элементу с номерами 0,0 присваивается значение 8;

mas23[1][0]=mas23[0][0]+4;   //     элементу  с     номерами  1,0

присваивается значение 12.

Перегрузка операторов. Примеры.

В С# существует ряд операторов для работы со встроенными типами данных. Это операторы «+», «-», «!», «==», «!=» и т.д. Например, бинарный оператор «+» выполняет операцию сложения над численными типами данных. Этот же самый оператор над строками выполняет конкатенацию (склеивание двух строк). Это происходит потому, что оператор «+» перегружен в классе string.

Перегрузка оператора - это реализация своего собственного функционала оператора для конкретного класса. Перегрузка оператора похожа на перегрузку методов, но требует специального оформления. Для перегрузки операторов используется служебное слово operator. Если мы хотим перегрузить некоторый оператор, то в соответствующем классе мы должны создать общедоступный статический метод с именем operator имя_оператора. Например operator+ или operator*.

Рассмотрим пример:

Класс, в этом классе есть поле rub, в котором хранятся рубли и поле kop предназначенное для копеек. Мы перегрузим двуместный оператор + и одноместный ++, второй оператор будет увеличивать рубли на единицу.

class M{ int rub; int kop;

public int Rub {get {return rub;} set {if(value≥0) rub=value; else rub=0}};

public int Kop {get {return kop;} set {if(value<0) kop=0; else {kop=value%100; rub=rub+value/100;};

public static M operator+(M m1, M m2) {

M m=new M();

m.Rub=m1.Rub+m2.Rub;

m.Kop=m1.Kop+m2.Kop;

return m;}

M m1=new M();

m1.Rub=3; //4

m1.Kop=138; //38

M m2=new M();

m2.Rub=4;

m2.Kop=72;

M m3=m1+m2;

public static M operator++(M m)

{m.Rub++; return m; }

}

Пример: переопределим + и ++. + это будет сумма полей объекта, а ++ добавление к каждому полю единицу:

public class Rectangle1 {

                   public int x, y, s;

                   public static Rectangle1 operator + (Rectangle1 rec1, Rectangle1 rec2)

                   {

                              Rectangle1 re = new Rectangle1 ();

                              re.x=rec1.x+rec2.y;

                              re.y=rec1.y+rec2.x;

                              return re;

                                  

                   }

                   public static Rectangle1 operator ++ (Rectangle1 rect)

                   {

                              rect.x++;

                          rect.y++;

                              return rect;

                   }

       }

//в мейнформ

re2.x=Convert.ToInt16(textBox3.Text);
re2.y=Convert.ToInt16(textBox4.Text);
re2++;

Rectangle1 ren=re1+re2;

При перегрузке нельзя менять местность оператора.

Операторы проверки отношений можно перегружать только в парах:

== и != ), < и >, <= и >=.

Нельзя перегружать следующие операторы:

[ ] – функционал этого оператора предоставляют индексаторы,

() – функционал этого оператора предоставляют методы преобразования типов,

+=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>= краткие формы оператора присваивания будут автоматически доступны при перегрузке соответствующих операторов (+, -, * …).

Исключительные ситуации. Обработка исключений. Блоки try-catch. Примеры.

Исключительная ситуация (или исключение) - это ошибка, которая возникает во время выполнения программы. Обработка исключений – это описание реакции программы на подобные события (исключения) во время выполнения программы. Реакцией программы может быть корректное завершение работы программы, вывод информации об ошибке и запрос повторения действия (при вводе данных).

Примерами исключений может быть:

- деление на ноль;

- извлечение корня квадратного из отрицательного числа;

- конвертация некорректных данных из одного типа в другой;

- попытка открыть файл, которого не существует;

- доступ к несуществующему элементу массива;

- другое.

Управление С#-механизмом обработки исключений базируется на четырех ключевых словах: try, catch, throw и finally.

Ядром обработки исключений являются блоки try и catch. Ключевые слова try и catch работают всегда в паре; нельзя использовать слово try без catch или catch без try. В блок try записываются команды, которые могут сгенерировать исключение, в блоки catch фрагменты программы, обрабатывающие эти исключения.

С try-блоком может быть связан не один, а несколько блоков catch. Какой именно из них будет выполнен, определит тип исключения. Другими словами, будет выполнен тот блок catch, который предназначен для обработки сгенерированного исключения. а все остальные блоки catch будут проигнорированы. Если исключение не генерируется, try-блок завершается нормально, и все связанные с ним блоки catch пропускаются. Выполнение программы продолжается с первой команды, которая стоит после последнего блока catch. Таким образом, конкретный блок catch выполняется только в случае, если сгенерировано соответствующее исключение.

Пример обработки исключений. Вводится значение переменной i, затем выполняется деление на эту переменную. Фрагмент программы, записанный в блоке try, может сгенерировать два типа исключений, поэтому после него идут два блока catch

void Button1Click(object sender, EventArgs e)

                   {int i,j;

                              try{i=Convert.ToInt32(textBox1.Text);

                                          j=14/i;}

                              catch(FormatException u)

                              {MessageBox.Show("Ошибка данных", "Внимание"); }

                              catch(DivideByZeroException u)

                              {MessageBox.Show("На 0 делить нельзя", "Внимание");}

                   }

Пример: исключение, если число превышает длину массива

try{

       k=Convert.ToInt32(textBox5.Text);

       if (!((mass[k] is Circle) ||(mass[k] is Romb)))

       {

                   groupBox1.Enabled=true;

                   textBox3.Text=""; textBox4.Text=""; label5.Text="";

catch (System.IndexOutOfRangeException)

                              {

                                          MessageBox.Show (" Введен неправильный индекс ");

                              }

Наследование классов. Иерархии классов. Примеры.

Наследование – это создание нового класса путём добавления новых членов к уже существующему классу. Класс, к которому добавляются новые члены называется базовым или родительским классом, а вновь созданный класс производным или дочернимклассом.

Двоеточие после имени класса указывает компилятору на то, что класс является производным от другого класса. За двоеточием следует имя базового класса.

Напоминание: методы производного класса могут работать только с открытыми (public ) и защищёнными ( protected и protected internal) членами базового класса, и если классы находятся в одной сборке, то членами, имеющими уровень доступа internal. Но не могут работать с собственными ( private )членами базового класса.

Пример:

с lass cir: vec {

public int R;

public void fun(void)

{ return x*y+R;}}

Класс cir является наследником класса vec, метод fun использует наравне с полем R , поля базового класса x,y, что возможно в том случае, когда уровень доступности указанных полей либо public, protected.

Конструкторы не наследуются, но используются при создании объектов производных классов. При создании объекта производного класса, сначала вызывается конструктор базового класса, а затем производного класса.

По умолчанию, при создании объектов производного класса вызывается конструктор базового класса без параметров.

Если необходимо использование для базового класса конструктора с параметрами, нужно обязательно написать конструктор производного класса и в описании этого конструктора включить дополнительную запись. После имени конструктора в его описании поставить двоеточие, затем, написать ключевое слово base и в скобках значения параметров.

class B{ public int x;

public B(int xx) { x=xx; }

}

class C:B{

public C(int xx):base(xx) {}}

В С# нет множественного наследования классов, т.е. для у любого производного класса базовый класс всегда один. Сам базовый класс может быть производным от некоторого другого класса.

В качестве базовых типов могут выступать интерфейсы, в этом случае класс может быть наследником многих интерфейсов.

Запрет наследования: классы объявленные как sealed.

Класс String пространства имен System является закрытым для наследования.

class T{

       public int x,y;

       public int sum()

       {return x+y;}

       }

class P: T{

       public int z;

       }

class S: P{

       public int u;

       public int pr()

       {return x*z*u;}      }

В этом примере определены три класса: Т, P , S. Как мы видим из описания, класс Р является производным от класса Т, а на основе класса Р строится класс S. Таким образом, можно создавать весьма разветвленные иерархии классов.

                Отметим, что метод pr() класса S наравне с полем u, использует поля x,z, которые достались в наследство, такое оказалось возможным, потому, что поля имеют уровень доступа public. Производный класс получает в наследство все члены базового класса, но методы производного класса не могут напрямую работать с членами уровня доступа private, да и возможность работы с членами базового класса уровня internal, зависит от того в одной ли сборке находятся базовый и производный классы

 Иерархии классов часто изображается в виде схем. На рисунке 1, изображен пример иерархия классов. Мы видим, что производных классов от одного базового класса может быть несколько. Но у каждого производ