Изменение методов базового класса.



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

Например, метод sum класса S должен возвращать сумму всех полей этого класса, а  не только x+y. В этом случае, в производном классе заново описывается нужная версия метода. Рекомендуется при этом обозначить новую версию метода служебным словом new, но и без данной пометки все будет работать корректно.

class S: P{

    public int u;

    public int pr()

    {return x*z*u;}

public int sum()

        {return x+y+ z+u;}

    }       

Метод sum первоначально описан в классе Т, который является базовым для класса Р, а затем переопределен в классе S.

Создадим объект класса S

S s1= new S();

Дадим этому объекту еще одно имя – ссылку базового класса.

Р р1=s1;

Если для рассматриваемого объекта s1 вызвать метод sum через ссылку s1 (s1.sum()), то сработает метод, описанный в классе S. Если будем использовать ссылку базового класса p1.sum(), то будет вызван метод из класса Т. Класс Р не содержит описание этого метода, но он его получает как наследник класса Т. Таким образом вызываемая версия метода связана с типом ссылки, через которую этот метод вызывается. Во многих случаях такое решение удобно, но не во всех.

Виртуальные методы

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

Для решения подобных проблем используются виртуальные методы.

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

Например.

class N{

              public int p=2,q=3;

              public virtual int pr()

              {return p*q;}

    }

    class M: N{

              public int g=4;

              public override int pr()

              {return p*q*g;}

    }

    class K: M {

    public int r=5;

    public override int pr()

              {return p*q*g*r;}

    }

Виртуальный метод вычисляет произведение всех полей класса и описанных в этом классе и унаследованных. Рассмотрим следующий код

                N n = new M ();

                       int i = n . pr ();

                       n= new K();

                       int j = n.pr();

                           

Не смотря на то, что вызов метода pr осуществляется через одну и туже ссылку n, в первом случае будет вызван метод из класса М, а во втором случае из класса К. Виртуальный метод связан с типом объекта, тип ссылки через которую он вызывается, при этом не играет роли.

Операторы is и as.

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

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

Ссылка is Тип

Если ссылка указывает на ненулевой объект, который можно преобразовать к указанному типу, то оператор возвращает значение true, в противном случае, возвращает значение false. Например,

N n = new M ();

bool l 1= n is M ; //здесь оператор is вернет значение true

bool l 2= n is K ; //здесь оператор is вернет значение false , поскольку класс М является базовым для класса М.

Оператор is работает со всеми типами, оператор as работает только со ссылочными типами. Оператор as, выполняет преобразование типов, если оно возможно и возвращает значение null, в противном случае.

Так команда К к = n as К; запишет null в ссылку к.

Абстрактные классы

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

 На языке С# для описания базового класса используется служебное слово abstract. Абстрактные классы могут содержать точно такие же члены, как и обычные классы. Кроме того, они могут содержать и абстрактные методы – методы, не имеющие реализации. Абстрактные методы оформляются специальным образом. Во первых при их описании используется служебное слово abstract, а во вторых вместо тела метода ставится точка с запятой.

Пример.

abstract class Q{

public int x;

public int getX(){return x;}

abstract public string fun();}

Абстрактный класс Q, содержит поле х, не абстрактный метод getX() и абстрактный метод fun().

Абстрактные методы не могут содержаться в обычных классах. Если обычный класс является производным от абстрактного класса, то в нем все абстрактные методы должны быть определены с использованием служебного слова override.

class D:Q{

              override public string fun(){return “ Класс D”;}}

 

Массивы

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

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

Одномерные массивы

Сначала рассмотрим числовые массивы. Описывается массив следующим образом:

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

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

int [] mas 1; mas 1= new int [10];

Число элементов массива задается в момент его создания. Число элементов массива может быть задано переменной или некоторым арифметическим выражением. Например:

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

int [] mas2=new int[n];

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

Массив может быть создан с помощь инициализирующего значения, например:

int [] mas 3={1,4.-5,9,-4};

в этом случае, массив не только создается, но и задаются значения его элементов.

При создании массива с помощью оператора new, элементы обнуляются, т.е. каждый его элемент будет установлен в значение, принятое по умолчанию для соответствующего типа данных (например, элементы массива типа bool будут устанавливаться в false, а элементы массива типа int — в 0).

 Нумерация элементов массива начинается с 0, т.е. первый элемент массива будет иметь номер 0. Работа с массивом происходим стандартным образом:

mas 1[0]=6;//первому элементу массива mas 1 присвоено значение 6

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

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

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

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

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

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

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

 

Обработка исключений

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

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

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

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

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

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

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

- другое.

Управление С#-механизмом обработки исключений базируется на четырех ключевых словах: 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 делить нельзя", "Внимание");}

              }

Результат работы программы, при введенном нуле, показан на рисунке 1.

Рисунок 2. Результат обработки исключения.

 

Блок finally, содержит код, который должен быть выполнен во всех случаях и тогда, когда исключение генерируется и тогда, когда не генерируется. Например, освобождение ресурсов, выделенных блоку try. Классическим примером использования блока finally является закрытие файла. Чтобы сгенерировать исключение «вручную», используется ключевое слово throw

        

Варианты заданий.

В основе всех вариантов заданий лежит одна задача «Разработка программы, работающей с массивом объектов различных типов, принадлежащих одной иерархии классов». Варианты отличаются друг от друга различными иерархиями классов. Индивидуальным является и интерфейс программы, поскольку перечисленные ниже требования можно реализовать по-разному. Для разработки интерфейса программы нужно использовать компоненты визуальной среды программирования Microsoft Visual Studio.NET.

Общие требования к работе:

1. Создать иерархию классов, согласно, выбранному варианту задания. В качестве базового класса «Геометрическая фигура» использовать абстрактный класс. Этот класс должен иметь хотя бы один абстрактный метод, например, метод, предназначенный для вычисления площади фигуры.  Все остальные классы иерархии должны быть неабстрактными.

2. Создать массив ссылок базового типа. Число элементов в массиве должен определять пользователь.

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

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

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

6.  Пользователь может изменить значения полей любого элемента и вывести информацию о любом элементе массива. Программа должна сама диагностировать тип элемента, выполнять преобразование типов.

7. Программа должна иметь защиту от неправильного ввода данных и от выбора несуществующего элемента.

Варианты иерархий классов

(в этих вариантах указаны производные классы, базовый класс во всех вариантах - «Геометрическая фигура»)

1. Классы «Окружность» и «Прямоугольный треугольник» являются производными от класса «Геометрическая фигура». Класс «Конус» производный от класса «Окружность». В классе «Окружность» определяется длина окружности. Во всех классах, задающих плоскую фигуру, вычисляется площадь фигуры, для объемных тел вычисляется площадь полной поверхности. В классе «Прямоугольный треугольник» должен быть определен метод, вычисляющий периметр треугольника. В классе «Конус» должен быть определен метод, вычисляющий объем.

2. Классы «Окружность» и «Ромб» являются производными от класса «Геометрическая фигура». Класс «Цилиндр» является производным от класса «Окружность». Во всех классах, задающих плоскую фигуру, вычисляется площадь фигуры, для объемных тел вычисляется площадь полной поверхности. В классе «Окружность» определяется длина окружности. В классе «Ромб» вычисляется периметр. В классе «Цилиндр» вычисляется объем.

3.  Класс «Квадрат» являются производным от класса «Геометрическая фигура». Классы «Правильная четырехугольная призма», «Правильная четырехугольная пирамида» являются производными от класса «Квадрат». Во всех классах, задающих плоскую фигуру, вычисляется площадь фигуры, для объемных тел вычисляется площадь полной поверхности. В классе «Квадрат» вычисляется периметр и диагональ. В классах «Правильная четырехугольная призма», «Правильная четырехугольная пирамида» вычисляется объем.

4. Классы «Ромб», «Прямоугольник» являются производными от класса «Геометрическая фигура». Класс «Прямоугольный параллелепипед» является производным от класса «Прямоугольник». Во всех классах, задающих плоскую фигуру, вычисляется площадь фигуры, для объемных тел вычисляется площадь полной поверхности. В классах «Прямоугольник», «Ромб» вычисляется диагональ. В классе «Прямоугольный параллелепипед» вычисляется объем.

5. Классы «Окружность» и «Равнобедренный треугольник» являются производными от класса «Геометрическая фигура». Класс «Цилиндр» является производным от класса «Окружность». Во всех классах, задающих плоскую фигуру, вычисляется площадь фигуры, для объемных тел вычисляется площадь полной поверхности. В классе «Окружность» вычисляется длина окружности. В классе «Равнобедренный треугольник»» вычисляется периметр. В классе «Цилиндр» вычисляется объем.

6. Классы «Окружность» и «Ромб» являются производными от класса «Геометрическая фигура». Класс «Конус» является производным от класса «Окружность». Во всех классах, задающих плоские фигуру, вычисляется площадь фигуры, для объемных тел вычисляется площадь полной поверхности. В классе «Окружность» вычисляется диаметр, а в классе «Ромб» - периметр. В классе «Конус» должен быть определен метод, вычисляющий объем.

7. Классы «Окружность», «Равнобедренный треугольник», «Квадрат» являются производными от класса «Геометрическая фигура». Класс «Правильная четырехугольная пирамида» являются производным от класса «Квадрат». Во всех классах, задающих плоские фигуру, вычисляется площадь фигуры, для объемных тел вычисляется площадь полной поверхности. В классе «Окружность» вычисляется диаметр. В классах «Равнобедренный треугольник » и «Квадрат» определить методы, вычисляющие периметры. В классе «Правильная четырехугольная пирамида» определить метод, вычисляющий объем.

8. Классы «Окружность», «Равнобедренный треугольник», «Ромб» являются производными от класса «Геометрическая фигура». Класс «Конус» производный от класса «Окружность». Во всех классах, задающих плоскую фигуры, вычисляется площадь фигуру, для объемных тел вычисляется площадь полной поверхности. В классе «Окружность» определить метод, вычисляющий диаметр. В классах «Равнобедренный треугольник » и «Ромб» определить методы, вычисляющие периметры.

9. Классы «Окружность», «Прямоугольник» и «Равнобокая трапеция» являются производными от класса «Геометрическая фигура». Класс «Конус» является производным от класса «Окружность». Во всех классах, задающих плоскую фигуру, вычисляется площадь фигуры, для объемных тел вычисляется площадь полной поверхности. В классах «Прямоугольник» и «Равнобокая трапеция» вычисляются периметры. В классе «Конус» должен быть определен метод, вычисляющий объем.

10. Классы «Окружность» и «Ромб» являются производными от класса «Геометрическая фигура». Класс «Конус» является производным от класса «Окружность». Во всех классах, задающих плоскую фигуру, вычисляется площадь фигуры, для объемных тел вычисляется площадь полной поверхности. В классе «Ромб» определить метод, вычисляющий сторону, а в классе «Окружность» - вычисляющий диаметр. В классе «Конус» определить метод, вычисляющий объем

11. Классы «Правильный шестиугольник», «Правильный треугольник», «Квадрат» являются производными от класса «Геометрическая фигура». Класс «Куб» является производным от класса «Квадрат». Во всех классах, задающих плоскую фигуру, вычисляется площадь фигуры, для объемных тел вычисляется площадь полной поверхности. В классах «Правильный треугольник», «Правильный шестиугольник» и «Квадрат» вычисляются периметры. В классе «Куб» вычисляется объем.

12. Классы «Правильный шестиугольник», «Правильный треугольник», «Ромб» являются производными от класса «Геометрическая фигура». Класс «Правильная шестиугольная призма» является производным от класса «Правильный шестиугольник. Во всех классах, задающих плоскую фигуру, вычисляется площадь фигуры, для объемных тел вычисляется площадь полной поверхности. В классах «Правильный треугольник», «Правильный шестиугольник» и «Ромб» определить методы, вычисляющие периметры. В классе «Правильная шестиугольная призма» вычисляется объем.

13. Классы «Окружность» и «Правильный треугольник» являются производными от класса «Геометрическая фигура». Класс «Правильная треугольная призма» является производным от класса «Правильный треугольник». Во всех классах, задающих плоскую фигуру, вычисляется площадь фигуры, для объемных тел вычисляется площадь полной поверхности. В классе «Окружность» вычисляются диаметр и  длина окружности. В классе «Правильная треугольная призма» определить метод, вычисляющий объем.

14. Классы «Ромб» и «Правильный треугольник» являются производными от класса «Геометрическая фигура». Класс «Правильная треугольная пирамида» является производным от класса «Правильный треугольник». Во всех классах, задающих плоскую фигуру, вычисляется площадь фигуры, для объемных тел вычисляется площадь полной поверхности. В классах «Ромб» и «Правильный треугольник» вычисляется периметр. В классе «Правильная треугольная пирамида» вычисляется объем.

15. Классы «Окружность» и «Квадрат» являются производными от класса «Геометрическая фигура». Класс ы «Правильная четырехугольная призма» и «Куб» являются производными от класса «Квадрат». Во всех классах, задающих плоскую фигуру, вычисляется площадь фигуры, для объемных тел вычисляется площадь полной поверхности. В классе «Окружность» вычисляется длина окружности. В классе «Квадрат» вычисляется периметр. В классах «Правильная четырехугольная призма» и «Куб» вычисляется объем.

16. Классы «Окружность», «Прямоугольный треугольник», «Правильный треугольник » являются производными от класса «Геометрическая фигура». Класс «Правильная треугольная пирамида» является производным от класса «Правильный треугольник». Во всех классах, задающих плоскую фигуру, вычисляется площадь фигуры, для объемных тел вычисляется площадь полной поверхности. В классе «Окружность» определить метод, вычисляющий диаметр. В классах «Прямоугольный треугольник» и «Правильный треугольник» вычисляются периметры. В классе «Правильная треугольная пирамида» вычисляется объем.

17. Классы «Окружность», «Правильный треугольник», «Ромб » являются производными от класса «Геометрическая фигура». Класс «Правильная треугольная призма» является производным от класса «Правильный треугольник». Во всех классах, задающих плоскую фигуру, вычисляется площадь фигуры, для объемных тел вычисляется площадь полной поверхности. В классе «Окружность» определить метод, вычисляющий диаметр. В классах «Прямоугольный треугольник» и «Ромб» вычисляются периметры. В классе «Правильная треугольная призма» вычисляется объем.

18. Классы «Правильный шестиугольник», «Квадрат» являются производными от класса «Геометрическая фигура». Класс «Правильная четырехугольная призма» является производным от класса «Квадрат». Во всех классах, задающих плоскую фигуру, вычисляется площадь фигуры, для объемных тел вычисляется площадь полной поверхности. В классе «Квадрат» определить метод, вычисляющий диагональ. В классах, «Правильный шестиугольник» и «Квадрат» вычисляются периметры. В классе «Правильная четырехугольная призма» определить метод, вычисляющий объем.

19.  Классы «Окружность», «Сектор», «Прямоугольник» являются производными от класса «Геометрическая фигура». Класс «Конус» является производным от класса «Окружность». Во всех классах, задающих плоскую фигуру, вычисляется площадь фигуры, для объемных тел вычисляется площадь полной поверхности. В классе «Прямоугольник» еще определить метод, вычисляющий диагональ. В классе «Окружность» еще определить метод, вычисляющий диаметр. В классе «Сектор» определить метод, вычисляющий длину дуги. В классе «Конус» вычисляется объем.

20.  Классы «Окружность», «Сектор», «Ромб» являются производными от класса «Геометрическая фигура». Класс «Цилиндр» является производным от класса «Окружность». Во всех классах, задающих плоскую фигуру, вычисляется площадь фигуры, для объемных тел вычисляется площадь полной поверхности. В классе «Ромб» вычисляется периметр. В классе «Окружность» вычисляется длина окружности, а в классе «Сектор» - длина дуги. В классе «Цилиндр» вычисляется объем.

21. Классы «Окружность» и «Сектор» являются производными от класса «Геометрическая фигура». Класс «Конус» является производным от класса «Окружность». Во всех классах, задающих плоскую фигуру, вычисляется площадь фигуры, для объемных тел вычисляется площадь полной поверхности. В классе «Сектор» определить метод, вычисляющий длину дуги, а в классе «Окружность» - длину окружности. В классе «Конус» определить метод, вычисляющий объем.

22. Классы «Сектор» и «Квадрат» являются производными от класса «Геометрическая фигура». Класс «Куб» является производным от класса «Квадрат». Во всех классах, задающих плоскую фигуру, вычисляется площадь фигуры, для объемных тел вычисляется площадь полной поверхности.  В классе «Квадрат» определить метод, вычисляющий периметр, а в «Сектор» - длину дуги. В классе «Куб» определить метод, вычисляющий объем.

23. Классы «Окружность» и «Прямоугольник» являются производными от класса «Геометрическая фигура». Класс «Прямоугольный параллелепипед» является производным от класса «Прямоугольник». Во всех классах, задающих плоскую фигуру, вычисляется площадь фигуры, для объемных тел вычисляется площадь полной поверхности. В классе «Прямоугольник» вычисляется периметр, а в классе «Окружность» - длина окружности. В классе «Прямоугольный параллелепипед» вычисляется объем.

24. . Классы «Сектор», «Прямоугольник » являются производными от класса «Геометрическая фигура». Класс «Прямоугольный параллелепипед» является производным от класса «Прямоугольник». Во всех классах, задающих плоскую фигуру, вычисляется площадь фигуры, для объемных тел вычисляется площадь полной поверхности. В классе «Прямоугольник» вычисляется периметр, а в классе «Сектор» - длина дуги. В классе «Прямоугольный параллелепипед» вычисляется объем.


Дата добавления: 2019-07-15; просмотров: 277; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!