theme changed
This commit is contained in:
		
							
								
								
									
										600
									
								
								labs/lab7/report.typ
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										600
									
								
								labs/lab7/report.typ
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,600 @@ | ||||
| #set text(size: 1.3em) | ||||
|  | ||||
| #show raw.where(block: false): box.with( | ||||
|   fill: luma(240), | ||||
|   inset: (x: 3pt, y: 0pt), | ||||
|   outset: (y: 3pt), | ||||
|   radius: 2pt, | ||||
| ) | ||||
|  | ||||
| #show raw.where(block: true): block.with( | ||||
|   fill: luma(240), | ||||
|   inset: 10pt, | ||||
|   radius: 4pt, | ||||
| ) | ||||
|      | ||||
| // title | ||||
|      | ||||
| #align(center)[Санкт-Петербургский национальный исследовательский университет информационных технологий, механики и оптики] | ||||
| \ | ||||
| \ | ||||
| \ | ||||
| #align(center)[Факультет инфокоммуникационных технологий] | ||||
| #align(center)[Направление подготовки 11.03.02] | ||||
| \ | ||||
| \ | ||||
| #align(center)[Лабораторная работа №7] | ||||
| #align(center)[Создание иерархии классов] | ||||
| \ | ||||
| \ | ||||
| \ //#align(center)[Вариант 19] | ||||
| \ | ||||
| \ | ||||
| \ | ||||
| \ | ||||
| \ | ||||
| \ | ||||
| \ | ||||
| #align(right)[Выполнил:] | ||||
| #align(right)[Дощенников Никита Андреевич] | ||||
| #align(right)[Группа: К3221] | ||||
| #align(right)[Проверил:] | ||||
| #align(right)[Иванов Сергей Евгеньевич] | ||||
| \ | ||||
| \ | ||||
| #align(center)[Санкт-Петербург] | ||||
| #align(center)[2025] | ||||
|  | ||||
| #pagebreak() | ||||
|      | ||||
| === Цель работы:  | ||||
|  | ||||
| Изучение наследования как важного элемента объектно-ориентированного программирования и приобретение навыков реализации иерархии классов. | ||||
|  | ||||
| === Упражнение 1. Реализация наследования классов. | ||||
|  | ||||
| В этом упражнении я использовал наследование для построения иерархии между классами, имеющих отношение типа "является". Вы добавите новый класс `Item`, который будет являться базовым для уже имеющегося класса `Book`. | ||||
|  | ||||
| ```cs | ||||
| using System;  | ||||
|  | ||||
| abstract class Item  | ||||
| { | ||||
|     protected long invNumber; | ||||
|     protected bool taken; | ||||
|  | ||||
|     public Item(long invNumber, bool taken) | ||||
|     { | ||||
|         this.invNumber = invNumber; | ||||
|         this.taken = taken; | ||||
|     } | ||||
|  | ||||
|     public Item() | ||||
|     { | ||||
|         this.taken = true; | ||||
|     } | ||||
|  | ||||
|     public bool IsAvailable() | ||||
|     { | ||||
|         return taken; | ||||
|     } | ||||
|  | ||||
|     public long GetInvNumber() | ||||
|     { | ||||
|         return invNumber; | ||||
|     } | ||||
|  | ||||
|     private void Take() | ||||
|     { | ||||
|         taken = false; | ||||
|     } | ||||
|  | ||||
|     public void TakeItem() | ||||
|     { | ||||
|         if (this.IsAvailable()) | ||||
|             this.Take(); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     abstract public void Return(); | ||||
|  | ||||
|     public virtual void Show() | ||||
|     { | ||||
|         Console.WriteLine("Состояние единицы хранения:\n Инвентарный номер: {0}\n Наличие: {1}", invNumber, taken); | ||||
|     } | ||||
| } | ||||
| ``` | ||||
|  | ||||
| ```cs  | ||||
| using System; | ||||
|  | ||||
| class Book : Item | ||||
| { | ||||
|     private String author; | ||||
|     private String title; | ||||
|     private String publisher; | ||||
|     private int pages; | ||||
|     private int year; | ||||
|     private bool returnSrok; | ||||
|  | ||||
|     private static double price = 9; | ||||
|  | ||||
|     static Book() | ||||
|     { | ||||
|         price = 10; | ||||
|     } | ||||
|  | ||||
|     public Book() | ||||
|     { | ||||
|  | ||||
|     } | ||||
|  | ||||
|  | ||||
|     public Book(String author, String title, String publisher, int pages, int year, long invNumber, bool taken) : base (invNumber, taken) | ||||
|     { | ||||
|         this.author = author; | ||||
|         this.title = title; | ||||
|         this.publisher = publisher; | ||||
|         this.pages = pages; | ||||
|         this.year = year; | ||||
|     } | ||||
|  | ||||
|     public Book(String author, String title) | ||||
|     { | ||||
|         this.author = author; | ||||
|         this.title = title; | ||||
|     } | ||||
|  | ||||
|     public void SetBook(String author, String title, String publisher, int pages, int year) | ||||
|     { | ||||
|         this.author = author; | ||||
|         this.title = title; | ||||
|         this.publisher = publisher; | ||||
|         this.pages = pages; | ||||
|         this.year = year; | ||||
|     } | ||||
|  | ||||
|     public static void SetPrice(double price) | ||||
|     { | ||||
|         Book.price = price; | ||||
|     } | ||||
|  | ||||
|  | ||||
|     public override void Show() | ||||
|     { | ||||
|         Console.WriteLine("\nКнига:\n Автор: {0}\n Название: {1}\n Год издания: {2}\n {3} стр.\n Стоимость аренды: {4}", author, title, year, pages, Book.price); | ||||
|         base.Show(); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     public double PriceBook(int s) | ||||
|     { | ||||
|         double cost = s * price; | ||||
|         return cost; | ||||
|     } | ||||
|  | ||||
|     public void ReturnSrok() | ||||
|     { | ||||
|         returnSrok = true; | ||||
|     } | ||||
|  | ||||
|     public override void Return() | ||||
|     { | ||||
|         taken = returnSrok; | ||||
|     } | ||||
| } | ||||
| ``` | ||||
|  | ||||
| Тесты:  | ||||
|  | ||||
| ```cs  | ||||
| public static void Main(string[] args) | ||||
| { | ||||
|     Item item1 = new Item(); | ||||
|     item1.Show(); | ||||
| } | ||||
| ``` | ||||
|  | ||||
| === Упражнение 2. Использование конструкторов. | ||||
|  | ||||
| В этом упражнении я определил конструкторы в базовом и в производном классах и реализуете их выполнение в обоих классах с помощью ключевого слова `base`, которое позволяет вызвать конструктор базового класса. | ||||
|  | ||||
| ```cs | ||||
| using System; | ||||
|  | ||||
| class Magazine : Item  | ||||
| { | ||||
|     private String volume; | ||||
|     private int number; | ||||
|     private String title; | ||||
|     private int year; | ||||
|  | ||||
|     public Magazine(String volume, int number, String title, int year, long invNumber, bool taken) : base(invNumber, taken) | ||||
|     { | ||||
|         this.volume = volume; | ||||
|         this.number = number; | ||||
|         this.title = title; | ||||
|         this.year = year; | ||||
|     } | ||||
|  | ||||
|     public Magazine() | ||||
|     {} | ||||
|  | ||||
|     public override void Show() | ||||
|     { | ||||
|         Console.WriteLine("\nЖурнал:\n Том: {0}\n Номер: {1}\n Название: {2}\n Год выпуска: {3}", volume, number, title, year); | ||||
|         base.Show(); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     public override void Return() | ||||
|     { | ||||
|         taken = true; | ||||
|     } | ||||
|  | ||||
| } | ||||
| ``` | ||||
|  | ||||
| Тесты: | ||||
|  | ||||
| ```cs | ||||
| public static void Main(string[] args) | ||||
| { | ||||
|         Book b2 = new Book("Толстой Л. Н.", "Война и мир", "Наука и жизнь", 1234, 2013, 101, true); | ||||
|  | ||||
|         b2.Show(); | ||||
|         b2.TakeItem(); | ||||
|         b2.Show(); | ||||
|  | ||||
|         Magazine mag1 = new Magazine("О природе", 5, "Земля и мы", 2014, 1235, true); | ||||
|         mag1.Show(); | ||||
| } | ||||
| ``` | ||||
|  | ||||
| Пример:  | ||||
|  | ||||
| #align(center)[#image("assets/1.png")] | ||||
|  | ||||
| === Упражнение 3. Переопределение методов. | ||||
|  | ||||
| В этом упражнении я реализовал механизм полиморфизма с помощью виртуальных методов и их переопределения в производных классах. | ||||
|  | ||||
| ```cs | ||||
| public static void Main(string[] args) | ||||
| { | ||||
|     Book b2 = new Book("Толстой Л. Н.", "Война и мир", "Наука и жизнь", 1234, 2013, 101, true); | ||||
|  | ||||
|     b2.Show(); | ||||
|     b2.TakeItem(); | ||||
|     b2.Show(); | ||||
|  | ||||
|  | ||||
|     Magazine mag1 = new Magazine("О природе", 5, "Земля и мы", 2014, 1235, true); | ||||
|     mag1.Show(); | ||||
|  | ||||
|     Console.WriteLine("\n Тестирование полиформизма"); | ||||
|     Item it; | ||||
|  | ||||
|     it = b2; | ||||
|     it.TakeItem(); | ||||
|     it.Return(); | ||||
|     it.Show(); | ||||
|  | ||||
|     it = mag1; | ||||
|     it.TakeItem(); | ||||
|     it.Return(); | ||||
|     it.Show(); | ||||
| } | ||||
| ``` | ||||
|  | ||||
| Пример:  | ||||
|  | ||||
| #align(center)[#image("assets/2.png")] | ||||
|  | ||||
| === Упражнение 4. Применение абстрактного класса и абстрактных методов.  | ||||
|  | ||||
| В этом упражнении я сделал базовый класс и один из его методов абстрактным. | ||||
|  | ||||
| Тесты и примеры совпадают с предыдущим упражнением. | ||||
|  | ||||
| === Упражнение 5. Реализации модели включения. | ||||
|  | ||||
| В этом упражнении я реализовал отношение "имеет", известное под названием модели включения или агрегации. | ||||
|  | ||||
| ```cs | ||||
| using System; | ||||
|  | ||||
| class Point | ||||
| { | ||||
|     private double x; | ||||
|     private double y; | ||||
|  | ||||
|     public Point(double x, double y) | ||||
|     { | ||||
|         this.x = x; | ||||
|         this.y = y; | ||||
|     } | ||||
|  | ||||
|     public Point () | ||||
|     {} | ||||
|  | ||||
|     public void Show() | ||||
|     { | ||||
|         Console.WriteLine("Точка с координатами: ({0}, {1})", x, y); | ||||
|     } | ||||
|  | ||||
|     public double Dlina(Point p) | ||||
|     { | ||||
|         double Dl = Math.Sqrt((this.x - p.x) * (this.x - p.x) + (this.y - p.y) * (this.y - p.y)); | ||||
|         return Dl; | ||||
|     } | ||||
|  | ||||
|     public override string ToString() | ||||
|     { | ||||
|         string ss = x + " ; " + y; | ||||
|         return ss; | ||||
|     } | ||||
| } | ||||
| ``` | ||||
|  | ||||
| ```cs | ||||
| using System; | ||||
|  | ||||
| class Line | ||||
| { | ||||
|     private Point pStart; | ||||
|     private Point pEnd; | ||||
|  | ||||
|     public Line(Point pStart, Point pEnd) | ||||
|     { | ||||
|         this.pStart = pStart; | ||||
|         this.pEnd = pEnd; | ||||
|     } | ||||
|  | ||||
|     public Line() | ||||
|     { } | ||||
|  | ||||
|     public void Show() | ||||
|     { | ||||
|         Console.WriteLine("Отрезок с координатами: ({0}) - ({1})", pStart, pEnd); | ||||
|     } | ||||
|  | ||||
|     public double DlinL() | ||||
|     { | ||||
|         return pStart.Dlina(pEnd); | ||||
|     } | ||||
| } | ||||
| ``` | ||||
|  | ||||
| Тесты:  | ||||
|  | ||||
| ```cs | ||||
| using System; | ||||
|  | ||||
| public class Program | ||||
| { | ||||
|     public static void Main(string[] args) | ||||
|     { | ||||
|         Point p1 = new Point(); | ||||
|         p1.Show(); | ||||
|         Point p2 = new Point(12, 13); | ||||
|         p2.Show(); | ||||
|  | ||||
|         Line line = new Line(p1, p2); | ||||
|         line.Show(); | ||||
|  | ||||
|         double dtr = line.DlinL(); | ||||
|         Console.WriteLine("Длина отрезка " + dtr); | ||||
|     } | ||||
| } | ||||
| ``` | ||||
|  | ||||
| Примеры:  | ||||
|  | ||||
| #align(center)[#image("assets/3.png")] | ||||
|  | ||||
| === Упражнение 6. Реализация отношения ассоциации между классами. | ||||
|  | ||||
| В этом упражнении я создал класс, моделирующий игральную кость и класс игрока, который связан с классом игры отношением ассоциации - каждый отдельный сеанс игры связан с конкретным игроком, бросающим кубик.  | ||||
|  | ||||
| ```cs | ||||
| using System; | ||||
|  | ||||
| class IgralnayaKost  | ||||
| { | ||||
|     Random r; | ||||
|  | ||||
|     public IgralnayaKost() | ||||
|     { | ||||
|         r = new Random(); | ||||
|     } | ||||
|  | ||||
|     public int random() | ||||
|     { | ||||
|         int res = r.Next(6) + 1; | ||||
|         return res; | ||||
|     } | ||||
| } | ||||
| ``` | ||||
|  | ||||
| ```cs | ||||
| using System; | ||||
|  | ||||
| class Gamer | ||||
| { | ||||
|     string Name; | ||||
|     IgralnayaKost seans; | ||||
|  | ||||
|     public Gamer(string name) | ||||
|     { | ||||
|         Name = name; | ||||
|         seans = new IgralnayaKost(); | ||||
|     } | ||||
|  | ||||
|     public int SeansGame() | ||||
|     { | ||||
|         return seans.random(); | ||||
|     } | ||||
|  | ||||
|     public override string ToString() | ||||
|     { | ||||
|         return Name; | ||||
|     } | ||||
| } | ||||
| ``` | ||||
|  | ||||
| Тесты:  | ||||
|  | ||||
| ```cs | ||||
| public static void Main(string[] args) | ||||
| { | ||||
|     Gamer g1 = new Gamer("Niko"); | ||||
|  | ||||
|     for (int i = 1; i <= 6; i++) | ||||
|     { | ||||
|         Console.WriteLine("Выпало количество очков {0} для игрока {1}", g1.SeansGame(), g1.ToString()); | ||||
|     } | ||||
| } | ||||
| ``` | ||||
|  | ||||
| Примеры: | ||||
|  | ||||
| #align(center)[#image("assets/4.png")] | ||||
|  | ||||
| === Упражнение 7. Реализация прогрессии. | ||||
|  | ||||
| В этом упражнении я определил абстрактный класс `Progression`, описывающий прогрессии. В этом классе определил абстрактный метод `GetElement` с целочисленным параметром `k`, возвращающий элемент прогрессии. Определил два производных класса `ArithmeticProgression` и `GeometricProgression`, описывающие арифметическую и геометрическую прогрессии. В каждом из классов определил конструктор, задающий параметры прогрессии и перегрузил унаследованный метод `GetElement`. | ||||
|  | ||||
| ```cs | ||||
| using System; | ||||
|  | ||||
| abstract class Progression | ||||
| { | ||||
|     public abstract int GetElement(int k); | ||||
|     public abstract int Sum(int n); | ||||
| } | ||||
| ``` | ||||
|  | ||||
| ```cs | ||||
| using System; | ||||
|  | ||||
| class ArithmeticProgression : Progression | ||||
| { | ||||
|     private int a0; | ||||
|     private int b; | ||||
|  | ||||
|     public ArithmeticProgression(int a0, int b) | ||||
|     { | ||||
|         this.a0 = a0; | ||||
|         this.b = b; | ||||
|     } | ||||
|  | ||||
|     public override int GetElement(int k) | ||||
|     { | ||||
|         return a0 + (k - 1) * b; | ||||
|     } | ||||
|  | ||||
|     public override int Sum(int n) | ||||
|     { | ||||
|         return (2 * a0 + (n - 1) * b) * n / 2; | ||||
|     } | ||||
| } | ||||
| ``` | ||||
|  | ||||
| ```cs | ||||
| using System; | ||||
|  | ||||
| class GeometricProgression : Progression | ||||
| { | ||||
|     private int p0; | ||||
|     private int q; | ||||
|  | ||||
|     public GeometricProgression(int p0, int q) | ||||
|     { | ||||
|         this.p0 = p0; | ||||
|         this.q = q; | ||||
|     } | ||||
|  | ||||
|     public override int GetElement(int k) | ||||
|     { | ||||
|         return p0 * (int)Math.Pow(q, k - 1); | ||||
|     } | ||||
|  | ||||
|     public override int Sum(int n) | ||||
|     { | ||||
|         if (q == 1) return p0 * n; | ||||
|         return p0 * (int)((Math.Pow(q, n) - 1) / (q - 1)); | ||||
|     } | ||||
| } | ||||
| ``` | ||||
|  | ||||
| Тесты:  | ||||
|  | ||||
| ```cs | ||||
| public static void Main(string[] args) | ||||
| { | ||||
|     Progression arith = new ArithmeticProgression(2, 3); | ||||
|     Progression geom = new GeometricProgression(2, 2); | ||||
|  | ||||
|     Console.WriteLine("Арифметическая прогрессия:"); | ||||
|     Console.WriteLine("5-й элемент = " + arith.GetElement(5)); | ||||
|     Console.WriteLine("Сумма 5 элементов = " + arith.Sum(5)); | ||||
|  | ||||
|     Console.WriteLine("\nГеометрическая прогрессия:"); | ||||
|     Console.WriteLine("5-й элемент = " + geom.GetElement(5)); | ||||
|     Console.WriteLine("Сумма 5 элементов = " + geom.Sum(5)); | ||||
| } | ||||
| ``` | ||||
|  | ||||
| Пример:  | ||||
|  | ||||
| #align(center)[#image("assets/5.png")] | ||||
|  | ||||
| === Выводы. | ||||
|  | ||||
| В ходе проделанной работе я изучил наследование как важный элемент объектно-ориентированного программирования и приобрел навыки реализации иерархии классов. | ||||
|  | ||||
| === Code review. (by #link("https://zzzcode.ai")[zzzcode.ai]) | ||||
|  | ||||
| *Резюме* | ||||
|  | ||||
| Код представляет собой реализацию нескольких классов, включая `Gamer`, `Book`, `Magazine`, `Item`, `Triangle`, `Line`, `Point`, и прогрессии. Основная логика кода заключается в моделировании игровых сессий и библиотечных предметов. Однако, код требует улучшений в области стиля, структуры и обработки ошибок. | ||||
|  | ||||
| *Ошибка* | ||||
|  | ||||
| В классе `Gamer` отсутствует проверка на `null` для параметра `name` в конструкторе. Это может привести к исключению, если передать `null`. Также метод `random()` в классе `IgralnayaKost` не определен в предоставленном коде, что может вызвать ошибки компиляции. | ||||
|  | ||||
|  | ||||
| *Стиль кода* | ||||
|  | ||||
| Имена переменных и методов должны следовать соглашениям о наименовании C\#. Например, `Name` и `seans` следует переименовать в `name` и `session` соответственно. Рекомендуется использовать свойства вместо полей для обеспечения инкапсуляции. | ||||
|  | ||||
| *Структура кода* | ||||
|  | ||||
| Код разбит на несколько классов, что хорошо для организации. Однако, стоит рассмотреть возможность разделения на отдельные файлы для каждого класса, чтобы улучшить читаемость и поддержку. | ||||
|  | ||||
| *Читаемость* | ||||
|  | ||||
| Код в целом читаем, но использование комментариев и документации для методов и классов значительно улучшит понимание кода другими разработчиками. | ||||
|  | ||||
| *Производительность* | ||||
|  | ||||
| Код не содержит явных проблем с производительностью, однако использование статических методов и свойств может быть оптимизировано для уменьшения потребления памяти. | ||||
|  | ||||
| *Масштабируемость* | ||||
|  | ||||
| Код может быть расширен, но для этого потребуется более четкая архитектура. Например, использование интерфейсов для классов `Item`, `Book`, и `Magazine` может улучшить гибкость и масштабируемость. | ||||
|  | ||||
| *Безопасность* | ||||
|  | ||||
| Отсутствие проверки входных данных может привести к уязвимостям. Рекомендуется добавить валидацию для всех входных параметров, особенно в конструкторах. | ||||
|  | ||||
| *Обработка ошибок* | ||||
|  | ||||
| Код не содержит механизма обработки ошибок. Рекомендуется использовать конструкции `try-catch` для обработки возможных исключений, особенно в методах, которые могут вызывать ошибки, такие как `random()`. | ||||
|  | ||||
| *Заключение* | ||||
|  | ||||
| Код демонстрирует базовые принципы объектно-ориентированного программирования, но требует улучшений в области стиля, структуры и обработки ошибок. Рекомендуется провести рефакторинг для повышения читаемости и безопасности, а также добавить документацию для улучшения поддержки кода в будущем. | ||||
|  | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 nik
					nik