Дополнительные возможности ООП
Теоретические сведения
Цель работы
Научится использовать обработку ошибок, параметризацию классов и другие возможности ООП для улучшения структуры программы.
Задание
В этой работе:
- с помощью механизма исключений будет добавлен вывод информации об ошибках, допущенных пользователем при вводе хода или команды;
- с помощью параметризованного класса из класса Game будет вынесена работа с массивом состояний и будет обеспечена более безопасная работа с этим массивом;
- с помощью класса перечислений будет контролироваться множество используемых символов в игре «крестики-нолики».
Новые файлы
Использование классов из прошлых работ
Классы Point и Board напрямую берутся из 3 работы. Иерархия Input – из 4. Классы Game, AbstractState, StateBalda и StateXO будут переписаны для работы с исключениями и названы, соответственно, EGame, EAbstractState, EStateBalda и EStateXO.
Файл Exceptions.kt
Создайте класс:
open class GameException(message: String): Exception(message)
Создайте наследников этого класса:
- объект
WrongCommandException, который выбрасывается, если пользователь ввел неправильную команду; - объект
object NoCellException, который выбрасывается, если пользователь ввел координаты поля, которого нет на игровой доске; - класс
WrongStepException, объекты которого будут выбрасываться, если пользователь сделал ход не по правилам игры.
Новые классы
Класс StateList<T> содержит массив состояний и функции по работе с ним. Его конструктор выглядит следующим образом:
class StateList<T>(
init: T,
private val array: ArrayList<T> = ArrayList()
)
В классе нужно реализовать две функции: fun add(state: T) – для добавления нового состояния после хода и fun move(to: Int): T для перехода к состоянию с индексом to. В случае, если состояние с индексом to отсутствует в массиве состояния, функция fun move(to: Int): T должна выбросить исключение WrongCommandException.
Также в класс нужно добавить свойство state – текущее состояние (как и раньше, оно не хранится отдельно, а выбирается геттером из массива состояний).
Класс-перечисление Turn имеет два объекта, один соответствует «крестику», другой – «нолику». Также в классе нужно определить функцию next(), которая возвращает противоположный для текущего объекта объект типа Turn, и функцию toString().
Новая реализация старых классов
Класс EAbstractState отличается от AbstractState функциями checkStep и step.
Функция open fun checkStep(step: Step): Unit теперь не возвращает результат, а в случае ошибки просто выбрасывает исключение.
Функции fun step(step: Step): EAbstractState теперь не контролирует ошибки, если происходит ошибка она пробрасывается мимо этой функции выше.
Свойство abstract val gameResult: String? по прежнему может возвращать нулевое значение, поскольку отсутствие результата игры это не ошибка.
Класс EStateXO отличается от StateXO только родительским классом.
Класс EStateBalda отличается от StateBalda родительским классом и функцией checkStep, в которой выбрасывается исключение в случае неверного числа параметров хода.
В классе EGame свойство states получает тип StateList. В функциях takeBack и step больше не нужны проверки и они не возвращают значение. Если при выполнении этих функций возникают ошибки, то они пробрасываются выше и будут обработаны в функции game.
Основное изменение в функции game заключается в том, что блок обработки ввода пользователя when помещается в блок try. В блоке catch перехватываются ошибки типа GameException и в выходной поток печатается сообщение из перехваченной ошибки.