- Структура проекта
- Как работает основной код в Main
- Класс Time
- Класс House
- Классы Department и Employee
- Класс Gun
- Вспомогательные классы
Проект состоит из следующих классов:
Main- главный класс с точкой входа программыTime- класс для представления времени сутокHouse- класс для представления дома с этажамиGun- класс для представления пистолета с патронамиUserInput- класс для обработки пользовательского вводаCheck- класс с вспомогательными методами проверки- Пакет
Departamentсодержащий:Department- класс для представления отделаEmployee- класс для представления сотрудника
do{
if(choice == 2){
choiceTask = input.inputChoiceInt(1,4, "тему:\n1. Время\n2. Дом\n3. Отделы и сотрудники\n4. Пистолет");
}
switch (choiceTask) {
case 1: // Работа с Time
case 2: // Работа с House
case 3: // Работа с Department и Employee
case 4: // Работа с Gun
}
System.out.println("Повторить?\n1. Да\n2. К выбору задания\n3. Выход");
choice = input.inputDiaposonInt(1, 3, "вариант");
if(choice == 3){
exit = true;
}
} while (!exit);- Переменная
choiceTaskотвечает за выбор темы для демонстрации - Переменная
choiceуправляет поведением после выполнения задания:- 1 - повторить текущее задание
- 2 - вернуться к выбору темы
- 3 - выход из программы
- Цикл
do-whileобеспечивает непрерывную работу программы до явного выхода пользователем
Класс представляет время суток в 24-часовом формате, храня количество секунд, прошедших с начала суток.
Time()- создает время 00:00:00Time(int totalSeconds)- создает время из заданного количества секундTime(Time time)- конструктор копирования
getTotalSeconds()- возвращает общее количество секундsetTotalSeconds(int totalSeconds)- устанавливает время, проверяя корректность данных
@Override
public String toString() {
return String.format("%d:%02d:%02d", totalSeconds % 86400 / 3600,
totalSeconds % 3600 / 60, totalSeconds % 60);
}Используется статистический метод класса String - format
Форматирование времени:
totalSeconds % 86400 / 3600- вычисляет часы (остаток от деления на секунды в сутках)totalSeconds % 3600 / 60- вычисляет минутыtotalSeconds % 60- вычисляет секунды- Формат
%02d0 - флаг обеспечивающий вывод с ведущими нулями, 2 - кол-во ячеек, d - число.
Класс представляет дом с определенным количеством этажей. Реализован как объект с 1 полем, неизменяемым после создания.
House(int floor)- создает дом с указанным количеством этажейHouse(House house)- конструктор копирования
- Поле
floorобъявлено какfinal- нельзя изменить после создания - Валидация в конструкторе: этажи должны быть в диапазоне 0-164
- Автоматическое определение правильного окончания для слова "этаж"
@Override
public String toString() {
if (floor % 100 >= 11 && floor % 100 <= 14) {
return String.format("Дом с %d %s", floor, "этажами");
}
if(floor % 10 == 1){
return String.format("Дом с %d %s", floor, "этажом");
}
return String.format("Дом с %d %s", floor, "этажами");
}Определение падежа:
- Для чисел, оканчивающихся на 1 (кроме 11) - "этажом"
- Для чисел 11-14 - "этажами"
- Для остальных случаев - "этажами"
Классы Department и Employee были вынесены в отдельный пакет Departament по следующим причинам:
- Логическая группировка - эти классы тесно связаны и представляют единую логику
- Инкапсуляция - пакет позволяет контролировать видимость методов
- Предотвращение циклических зависимостей - четкое разделение ответственности
Представляет сотрудника с именем и связью с отделом.
Employee()- сотрудник без имени и отделаEmployee(String name)- сотрудник с именем без отделаEmployee(String name, Department department)- сотрудник с именем и отделомEmployee(Employee copyEmployee)- конструктор глубокого копирования
Во всех конструкторах классов делается проверка на исключения. Либо напрямую в конструкторе, либо через методы set[имя какого-либо поля], которые также обрабатывают исключения.
// Public методы - доступны извне пакета
public String getName() { return new String(name); }
public Department getDepartment() {
if (this.department == null) return null;
return new Department(department); // Возвращает копию
}
// Package-private методы - доступны только внутри пакета
Department getRefDepartment() { return this.department; }
void setDepartment(Department department) {
this.department = department;
}Обоснование различных областей видимости:
getRefDepartment()иsetDepartment()с package-private видимостью предотвращают несанкционированное изменение связей извне пакетаgetDepartment()возвращает копию отдела для обеспечения инкапсуляции- Перегрузка конструкторов повзоляют различные сценарии создания сотрудника
@Override
public String toString() {
if (this.department == null) { // находится ли сотрудник в каком либо отделе
...
return String.format("%s не находится ни в одном из отделов", this.getName());
}
if (this.department.getRefBoss() == this) { // если является боссом
...
return String.format("%s начальник отдела %s", this.getName(), depName);
}
///
// формирование String depName и String bossName
///
return String.format("%s работает в отделе %s, начальник которого %s",
this.getName(), depName, bossName);
}Представляет отдел с названием, начальником и списком сотрудников.
Department()- отдел без названияDepartment(String name)- отдел с названиемDepartment(String name, Employee boss)- отдел с названием и начальникомDepartment(String name, Employee boss, ArrayList<Employee> employees)- полная инициализацияDepartment(Department department)- конструктор глубокого копирования
Стандартное создание:
Без названия и начальника:
Без названия, начальника и сотрудника:
Управление сотрудниками:
public void addEmployee(Employee employee) {
if(employee != null && !this.employees.contains(employee)){
// Удаляем сотрудника из предыдущего отдела
if(employee.getRefDepartment() != null && employee.getRefDepartment() != this){
employee.getRefDepartment().removeEmployee(employee);
}
this.employees.add(employee);
employee.setDepartment(this); // Используем package-private метод из класса Employee
}
}
public void removeEmployee(Employee employee) {
if(employee != null && this.employees.contains(employee)){
this.employees.remove(employee);
if (employee == this.boss){
this.boss = null; // Сброс начальника при удалении
}
employee.setDepartment(null);
}
}Добавление и удаление сотрудника из отдела происходит именно с помощью этих методов. Нельзя использовать setDepartament у объекта класса Employee.
// Public методы
public Employee getBoss() {
if(boss == null) return null;
return new Employee(boss); // Возвращает копию
}
// Package-private метод
Employee getRefBoss() { return this.boss; }Обоснование:
getRefBoss()позволяет работать с оригинальным объектом внутри пакета для эффективностиgetBoss()возвращает копию для защиты от внешних изменений
@Override
public String toString() {
String result = "Отдел\n==" + name + "==\n";
if (boss != null) {
result += "Начальник: " + boss.getName() + "\n";
} else {
result += "Начальник пока не назначен\n";
}
result += "Сотрудники:\n";
// Вывод списка сотрудников (исключая начальника)
// ...
return result;
}Вся информация по отделу формируется в String объект result.
Класс представляет пистолет с ограниченным количеством патронов.
Gun()- пистолет с 5 патронами по умолчаниюGun(int ammo)- пистолет с указанным количеством патроновGun(Gun copyGun)- конструктор копирования
public void shot(){ // стрельба
if(this.ammo > 0){
System.out.println("БАХ!");
this.ammo--;
} else {
System.out.println("Клац...");
}
}
public void reload(){ // перезарядка (по заданию не предусматривалось)
System.out.println("ПЕРЕЗАРЯДКА!!!");
this.ammo = 12; // Максимальная емкость
}Содержит методы валидации:
isInteger(String str)- проверка целого числаPositive(int num)- проверка неотрицательности
Обеспечивает безопасный ввод данных с консоли:
inputInt(),inputPositiveInt()- ввод чиселinputDiaposonInt()- ввод числа в диапазонеinputChoiceInt()- ввод выбора из менюinputString()- ввод строки










