Главная | Обратная связь | Поможем написать вашу работу!
МегаЛекции

Лабораторная работа 2 «Наследование».

 

В классе:

Реализуем два класса: «Точка на плоскости» (Point) и «Круг на плоскости» (Circle).

Реализацию каждого класса оформим в отдельном модуле.

 

1. Объекты класса «Точка на плоскости» (Point) будут характеризоваться двумя полями «x» и «y», хранящими координаты точки на плоскости и методами:

конструктор Point() – создание точки в начале координат;

конструктор Point(x,y) – создание точки с указанными координатами;

процедура Move(dx,dy) – перенос точки на вектор (dx,dy);

функция Info – возвращает строку с информацией об объекте.

 

2. Объекты класса «Круг на плоскости» (Circle) будут характеризоваться тремя полями «x», «y» и «r», хранящими соответственно координаты центра круга и его радиус. Также объект должен обладать следующими методами:

конструктор Circle() – создание круга с параметрами (0,0,1);

конструктор Circle(x,y,r) – создание круга с указанными параметрами;

процедура Move(dx,dy) – перенос круга на вектор (dx,dy);

функция GetSquare() – возвращает значение площади круга;

процедура SetSquare(Value) – изменяет площадь круга на значение (Value);

функция Info() – возвращает строку с информацией об объекте.

 

Логично данный класс не описывать «с нуля», а построить его на базе класса (Point). В этом случае, очевидно, что процедура Move(dx,dy) в классах (Circle) и (Point) выполняет аналогичные действия и может быть унаследована. Функция Info() также есть в обоих классах, но в (TCircle) выводится больше информации, поэтому создадим новый метод, перекрыв старый. Остальные методы уникальны. Их также опишем в классе – потомке.

 

Диаграмма классов

Point
#x,y: double
+Point() +Point(x,y) +Move(dx:double, dy:double) +Info():string

 
 

 


Circle:Point
-r: double
+Circle() +Circle(x,y,r:double) +SetSquare(value:double) +GetSquare():double +Info():string

 

Для доступа к полям x и y класса Point из его потомков и закрытия данных полей от остальных классов, эти поля объявляются с уровнем доступа protected (#).

 

Текст файла «Points.cs»:

 

Возможна следующая реализация класса Circle:

 

Как видно, конструктор класса «Круг»

повторяет действия конструктора базового класса «Точка»

 

 

В этом случае конструктор класса «Круг» можно записать короче

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

 

 

3. Тестирование классов выполним в консольном приложении, в несколько этапов.

 

На первом этапе просто проверим для каждого класса работу конструкторов и методов Info().

 

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

Информация о каждом объекте выводится на консоль:

 

Очевидно, что конструкторы работают корректно.

 


На втором этапе будем использовать принцип полиморфизма.

Для этого опишем массив объектов, указав тип каждого элемента как «Точка». Создание объектов оформим в методе Create(), а вывод информации – в методе Show().

 

static void Main(string[] args)

{

const int n = 6; //длина массива

Point[] p;

Create(out p, n);

Show(p);

Console.ReadLine();

}

 

В методе Create() будем создавать объекты и класса «Точка» и класса «Круг».

 

static void Create(out Point[] p, int k)

{

p = new Point[k];

Random rnd = new Random();

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

{

if (rnd.NextDouble() < 0.4)
p[i] = new Point(rnd.Next(10), rnd.Next(10));

else p[i] = new Circle(rnd.Next(10), rnd.Next(10), rnd.Next(8));

}

}

 

Класс объекта p[i] выбирается случайно. С вероятностью 0.4 это будет точка, а с вероятностью 0.6 – круг.

Вывод информации об объектах оформим в виде:

 

static void Show(Point[] p)

{

int k = p.Length;

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

{

Console.WriteLine("{0,2} - {1}",i,p[i].Info());

}

Console.WriteLine("-------------------------------");

}

 

В итоге, результат работы программы следующий:

Т.к. в методе Show() элементы массива p объявлены как объекты базового класса «Точка», то компилятор подставляет в качестве адреса функции Info() адрес данной функции из класса «Точка» (т.н. «раннее связывание»).

Если фактический класс отличается от базового, то следует сначала проверить это, а затем привести объект к правильному типу (кастинг). Заменим текст метода Show().

static void Show2(Point[] p)

{

int k = p.Length;

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

{

if (p[i] is Point)

Console.WriteLine("{0,2} - {1}", i, p[i].Info());

else Console.WriteLine("{0,2} - {1}", i, ((Circle)p[i]).Info());

}

Console.WriteLine("-------------------------------");

}

Здесь для объектов класса «Точка» вызывается базовый Info(), а для остальных типов – метод Info() класса «Круг». Однако результат остаётся прежним:

 

Наша ошибка в том, что все эти объекты являются объектами базового класса и условие в операторе if (p[i] is Point) всегда даёт значение true. Поменяем данное условие на более точное условие (p[i] is Circle)

 

static void Show3(Point[] p)

{

int k = p.Length;

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

{

if (p[i] is Circle)

Console.WriteLine("{0,2} - {1}", i, ((Circle)p[i]).Info());

else Console.WriteLine("{0,2} - {1}", i, p[i].Info());

}

Console.WriteLine("-------------------------------");

}

 

Теперь проверка работает корректно.

 

На третьем этапе добавим тестирование остальных методов класса. Для этого в теле программы организуем метод Transform(), включающий вызов методов наших классов.

static void Transform(Point[] p)

{

for (int i = 0; i < p.Length; i++)

{

if (p[i] is Circle)

((Circle)p[i]).SetSquare(10);

else p[i].Move(5,5);

}

}

 

Будем вызывать его, а затем метод Show() для проверки результатов:

 

static void Main(string[] args)

{

const int n = 6; //длина массива

Point[] p;

Create(out p, n);

Show(p);

Transform(p);

Show(p);

 

Console.ReadLine();

}

 

Результат запуска программы следующий.

 

Самостоятельно в классе

 

Реализовать в обоих классах следующие методы:

Simm() – переносит объект симметрично относительно начала координат. Для проверки работы метода примените его ко всем объектам и выполните (Show).

RoFrom(А) – расстояние до другого объекта (А). Здесь следует учесть, что для класса (Point) объект A должен быть этого же типа (т.к. Circle ещё не описан), а для класса (Circle) объект A может иметь и тот и другой тип (быть и точкой и кругом). Для проверки второго метода выведите квадратную таблицу N на N с подписями строк и столбцов, содержащую расстояние от i-го объекта до j-го (для желающих получить 4 или 5 на экзамене).

Дома:

 

Обязательная часть:

Поделиться:





Воспользуйтесь поиском по сайту:



©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...