Определить иерархию классов для варианта «тест, экзамен, выпускной экзамен, испытание»
28.02.2015, 10:54. Показов 15581. Ответов 5
Порядок выполнения работы.
1. Определить иерархию классов (в соответствии с вариантом).
2. Определить в классе статическую компоненту — указатель на нача-
ло связанного списка объектов и статическую функцию для просмотра
списка.
3. Реализовать классы.
4. Написать демонстрационную программу, в которой создаются
объекты различных классов и помещаются в список, после чего список
просматривается.
5. Сделать соответствующие методы не виртуальными и посмотреть,
что будет.
6. Реализовать вариант, когда объект добавляется в список при соз-
дании, т.е. в конструкторе (смотри пункт 6 следующего раздела).
Методические указания.
1. Для определения иерархии классов связать отношением наследо-
вания классы, приведенные в приложении (для заданного варианта). Из
перечисленных классов выбрать один, который будет стоять во главе ие-
рархии. Это абстрактный класс.
2. Определить в классах все необходимые конструкторы и деструк-
тор.
3. Компонентные данные класса специфицировать как protected.
4. Пример определения статических компонентов:
static person* begin; // указатель на начало списка
static void print(void); // просмотр списка
5. Статическую компоненту-данное инициализировать вне определе-
ния класса, в глобальной области.
6. Для добавления объекта в список предусмотреть метод класса, т.е.
объект сам добавляет себя в список. Например, a.Add() •объект a добавля-
ет себя в список.
Включение объекта в список можно выполнять при создании объек-
та, т.е. поместить операторы включения в конструктор. В случае иерархии
классов, включение объекта в список должен выполнять только конструк-
тор базового класса. Вы должны продемонстрировать оба этих способа.
7. Список просматривать путем вызова виртуального метода Show
каждого объекта.
8. Статический метод просмотра списка вызывать не через объект, а
через класс.
9. Определение классов, их реализацию, демонстрационную про-
грамму поместить в отдельные файлы.
Содержание отчета.
1. Титульный лист: название дисциплины; номер и наименование ра-
боты; фамилия, имя, отчество студента; дата выполнения.
2. Постановка задачи. Следует дать конкретную постановку, т.е. ука-
зать, какие классы должны быть реализованы, какие должны быть в них
конструкторы, компоненты-функции и т.д.
3. Иерархия классов в виде графа.
4. Определение пользовательских классов с комментариями.
5. Реализация конструкторов с параметрами и деструктора.
6. Реализация методов для добавления объектов в список.
7. Реализация методов для просмотра списка.
8. Листинг демонстрационной программы.
9. Объяснение необходимости виртуальных функций. Следует пока-
зать, какие результаты будут в случае виртуальных и не виртуальных
функций.
Вариант задания: тест, экзамен, выпускной экзамен, испытание;
Вот набросал код, но не понятно со списком!
C++ | ||
|
__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь
0
Лабораторная
работа
3 «Наследование».
В
классе:
Реализуем два
класса: «Точка на плоскости» (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(«——————————-«);
}
Теперь
проверка работает корректно.
На
третьем этапе добавим тестирование
остальных методов класса. Для этого в
классе Program
организуем метод 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 на экзамене).
Дома:
Обязательная
часть:
Написать
программу, в которой создается иерархия
классов.
1.
Определить иерархию классов (в соответствии
с вариантом).
2.
Реализовать классы.
3.
Написать демонстрационную программу,
в которой создаются объекты различных
классов и помещаются в массив, после
чего массив просматривается.
Методические
указания
1.
Для определения иерархии классов связать
отношением наследования классы,
приведенные в приложении (для заданного
варианта). Выбрать базовый класс и классы
– потомки (можно оставить 2 потомка).
2.
Определить в классах по 2 конструктора,
по 2 метода, не возвращающих значение и
по 2 метода, возвращающих значение.
Дополнительно в каждый класс включить
метод Info().
3.
Продумать набор полей классов так, чтобы
у каждого класса были свои данные.
Специфицировать их как как protected.
4.
В демонстрационной программе организовать
массив объектов разных классов, показав
работу конструктора и всех методов
отдельных классов.
5.
Определение классов, их реализацию,
демонстрационную программу поместить
в отдельные файлы.
Содержание
отчёта по лабораторной работе
1.
Титульный лист содержит номер и
наименование работы, фамилию, имя
студента.
2.
Постановка задачи. Следует дать конкретную
постановку, т.е. указать, какие классы
должны быть реализованы, какие должны
быть в них конструкторы, компоненты-функции
и т.д. (см. пример выше).
3.
Иерархия классов в виде Диаграммы
классов (из VStudio).
4.
Тексты файлов каждого класса (4 файла –
3 класса и Program).
5.
Скриншоты листинга работы программы.
Варианты
заданий (перечень классов):
-
студент,
преподаватель, персона, зав.кафедрой; -
служащий,
персона, рабочий, инженер; -
рабочий,
кадры, инженер, администрация; -
деталь,
механизм, изделие, узел; -
организация,
страховая компания, судостроительная
компания, завод; -
журнал,
книга, печатное издание, учебник; -
тест,
экзамен, выпускной экзамен, испытание; -
место,
область, город, мегаполис; -
игрушка,
продукт, товар, молочный продукт; -
квитанция,
накладная, документ, чек; -
автомобиль,
поезд, транспортное средство, экспресс; -
двигатель,
двигатель внутреннего сгорания, дизель,
турбореактивный двигатель; -
республика,
монархия, королевство, государство; -
млекопитающие,
парнокопытные, птицы, животное; -
корабль,
пароход, парусник, корвет.
Остальные
варианты – опять с номера 1 (16 делает 1,
17 – 2 и т.д.).
8
Соседние файлы в папке Задания
- #
- #
- #
- #
- #
- #
- #
- #
using System; using System.Collections.Generic; namespace TestConsole { /// <summary> /// Класс экзамен. /// </summary> class Exam { #region Fields /// <summary> /// ФИО студента. /// </summary> private string _fio; /// <summary> /// Дата экзамена. /// </summary> private DateTime _dateExam; /// <summary> /// Оценка. /// </summary> private int _appraisal; /// <summary> /// Перечень вопросов. /// </summary> private List<string> _listOfIssues; #endregion Fields #region Properties /// <summary> /// ФИО студента. /// </summary> public string FIO { get { return _fio; } set { if (_fio == value) return; _fio = value; } } /// <summary> /// Дата экзамена. /// </summary> public DateTime DateExam { get { return _dateExam; } set { if (_dateExam == value) return; _dateExam = value; } } /// <summary> /// Оценка. /// </summary> public int Appraisal { get { return _appraisal; } set { if (_appraisal == value) return; _appraisal = value; } } /// <summary> /// Перечень вопросов. /// </summary> public List<string> ListOfIssues { get { return _listOfIssues; } set { if (_listOfIssues == value) return; _listOfIssues = value; } } #endregion Properties #region Constructors /// <summary> /// Конструктор по умолчанию. /// </summary> public Exam() { } /// <summary> /// Конструктор с параметром. /// </summary> /// <param name="exam">Копируемый объект.</param> public Exam(Exam exam) { this._fio = exam._fio; this._dateExam = exam._dateExam; this._appraisal = exam._appraisal; this._listOfIssues = new List<string>(exam._listOfIssues); } #endregion Constructors } class Program { static void Main(string[] args) { Exam[] listExam = new Exam[5]; listExam[0] = new Exam(new Exam() { FIO = "Иванов Иван Иванович", DateExam = new DateTime(2016, 12, 23), Appraisal = 5, ListOfIssues = new List<string>() { "Вопрос 1?", "Вопрос 2?" } }); listExam[1] = new Exam(new Exam() { FIO = "Петров Петр Петрович", DateExam = new DateTime(2016, 12, 24), Appraisal = 5, ListOfIssues = new List<string>() { "Вопрос 3?", "Вопрос 4?" } }); listExam[2] = new Exam(); listExam[3] = new Exam(new Exam() { FIO = "Василий Васильевич Васильев", DateExam = new DateTime(2016, 12, 25), Appraisal = 5, ListOfIssues = new List<string>() { "Вопрос 5?", "Вопрос 6?" } }); listExam[4] = new Exam(); listExam[4].FIO = "Сидоров Сидор Сидорович"; listExam[4].DateExam = new DateTime(2016, 12, 26); listExam[4].Appraisal = 3; listExam[4].ListOfIssues = new List<string>(); listExam[4].ListOfIssues.Add("Вопрос 7?"); listExam[4].ListOfIssues.Add("Вопрос 8?"); _Show(listExam); Console.ReadKey(); } #region Methods /// <summary> /// Выводит на экран список объектов типа Exam. /// </summary> /// <param name="listExam">Выводимый список объектов.</param> private static void _Show(Exam[] listExam) { for(int i = 0; i < listExam.Length; i++) { Console.WriteLine("Фио: " + listExam[i].FIO); Console.WriteLine("Дата проведения экзамена: " + listExam[i].DateExam.ToString("yyyy.MM.dd")); Console.WriteLine("Оценка: " + listExam[i].Appraisal); // Проверяем, проиниализирован список или нет if (listExam[i].ListOfIssues != null) { for (int j = 0; j < listExam[i].ListOfIssues.Count; j++) { Console.WriteLine("Вопрос: " + listExam[i].ListOfIssues[j]); } } Console.WriteLine(); } } #endregion Methods } }
Аннотация: Цель: ознакомление с основой объектного подхода в языке C#, созданием объектов, классов и механизмом наследования.
Теоретические сведения
Классы и обьекты
Понятие класса является фундаментальным в ООП и служит основой для создания объектов. В описании класса определяются данные (т.е.
переменные) и код (т.е. методы), манипулирующий этими данными. Объекты являются экземплярами класса.
Методы и переменные, составляющие класс, называются членами
класса. При определении класса объявляются данные, которые он содержит, и код, манипулирующий этими данными. Данные содержатся в переменных экземпляра, которые определены классом, а код содержится в методах. В языке С# определены несколько специфических разновидностей
членов класса. К ним относятся: переменные экземпляра, статические переменные, константы, методы, конструкторы, деструкторы, индексаторы,
события, операторы и свойства.
Инициализация переменных в объекте (как в экземпляре класса)
производится непосредственно в конструкторе класса. В составе класса
может быть определено несколько конструкторов.
Синтаксис определения класса:
class имя_класса{ тип_доступа тип имя_переменной1; тип_доступа тип имя_переменной2; ... тип_доступа возвращаемый_тип имя_метода1(список_параметров) {тело_метода} }
где тип_доступа может принимать одно из следующих значений: public, private, protected, internal. Члены класса с типом доступа public являются общедоступными (т.е. доступны из любой точки
программы за пределами данного класса), с типом доступа protected –
внутри членов данного класса и его производных, с типом доступа private
– только для других членов данного класса. Тип доступа internal
применяется для типов, доступных в пределах одной сборки.
Приведем пример описания класса:
class Animal{ public string Name; private int Weight; protected int Type; public int Animal(int W, int T, string N){ Weight=W; Type=T; Name=N; } public int GetWeight(){return Weight;} }
Создание обьекта
Синтаксис:
имя_класса имя_обьекта = new имя_класса();
При создании обьекта (т.е. экземпляра класса) происходит вызов
соответствующего конструктора класса.
Понятия конструктора и деструктора
Под конструктором класса будем понимать метод для инициализации объекта при его создании. Конструктор имеет то же имя, что и его
класс. В конструкторах тип возвращаемого значения не указывается явно.
Конструкторы используются для присваивания начальных значений переменным экземпляра, определенным классом, и для выполнения любых
других процедур инициализации, необходимых для создания объекта.
Конструктор существует для любого класса, независимо от того, определен он в явном виде или нет. Умолчаниями языка С# предусмотрено
наличие конструктора, который присваивает нулевые значения всем переменным экземпляра (для переменных типов-значений) и значения null (для переменных ссылочного типа). В случае явного определения
конструктора класса конструктор по умолчанию не используется.
Синтаксис описания конструктора:
имя_класса(список_параметров) {тело_конструктора}
Под деструктором будем понимать метод, который автоматически
вызывается при уничтожении объекта класса (непосредственно перед началом процедуры «сборки мусора»). Деструкторы не имеют параметров и
не возвращают значений.
Синтаксис описания деструктора:
~имя_класса() {тело_деструктора}
Наследование
Под наследованием будем иметь в виду свойство, с помощью которого один объект может приобретать свойства другого. При этом поддерживается концепция иерархической классификации, имеющей направление
сверху вниз. При принятии концепции наследования, для вновь создаваемых объектов необходимо определять только те свойства, которые делают
его уникальным в пределах своего класса. Объект может наследовать общие атрибуты от родительских по отношению к нему классов.
Синтаксис описания объекта:
class имя_класса : имя_родительского_класса { тело_класса }
Пример описания объекта:
class Predator:Animal{ private int Speed; }
Наследование формирует иерархию классов на основе отношения
частичного порядка ISA («являться»).
Иерархия может быть построена и для объектов. В этом случае она
имеет структуру, которая строится на основе отношения структурного
вхождения («часть-целое»), при котором один объект является частью
другого.
Порядок выполнения работы
- Разработать методы и свойства для каждого из определяемых классов.
- Реализовать программу на C# в соответствии с вариантом исполнения.
Варианты заданий
Построить иерархию классов в соответствии с вариантом задания:
- Студент, преподаватель, персона, заведующий кафедрой
- Служащий, персона, рабочий, инженер
- Рабочий, кадры, инженер, администрация
- Деталь, механизм, изделие, узел
- Организация, страховая компания, нефтегазовая компания, завод
- Журнал, книга, печатное издание, учебник
- Тест, экзамен, выпускной экзамен, испытание
- Место, область, город, мегаполис
- Игрушка, продукт, товар, молочный продукт
- Квитанция, накладная, документ, счет
- Автомобиль, поезд, транспортное средство, экспресс
- Двигатель, двигатель внутреннего сгорания, дизель, реактивный двигатель
- Республика, монархия, королевство, государство
- Млекопитающее, парнокопытное, птица, животное
- Корабль, пароход, парусник, корвет