Сложение объектов
Часть раздела Объектно-ориентированное программирование путешествия по Lua на Coddy. Урок 26 из 70.
Ты уже видел, как метаметоды вроде __tostring и __eq позволяют настраивать поведение объектов. Теперь мы расширим это на арифметические операции, начав со сложения.
Метаметод __add определяет, что происходит при использовании оператора + между двумя объектами. Когда Lua видит a + b, он ищет __add в метатаблице любого из операндов.
local Vector = {}
Vector.__index = Vector
function Vector:new(x, y)
local obj = {x = x, y = y}
setmetatable(obj, Vector)
return obj
end
function Vector.__add(v1, v2)
return Vector:new(v1.x + v2.x, v1.y + v2.y)
endОбратите внимание: __add определена с точкой. Lua передаёт оба операнда как обычные аргументы, а форма с точкой задаёт имена обоих. Двоеточие тоже подошло бы, поскольку function Vector:__add(other) — это то же самое, что function Vector.__add(self, other), но форма с точкой является общепринятой. __add должна возвращать новый объект, а не изменять любой из исходных. Это делает операцию предсказуемой и безопасной.
local a = Vector:new(3, 4)
local b = Vector:new(1, 2)
local c = a + b
print(c.x, c.y) -- Вывод: 4 6Ключевой вывод состоит в том, что __add должен находиться в самой метатаблице (здесь — Vector), а не только в объекте. Поскольку мы устанавливаем Vector в качестве метатаблицы для всех экземпляров, они автоматически получают это общее поведение.
Задание
ЛегкоДавайте создадим класс Vector, который поддерживает сложение с помощью оператора +. Это ваш первый шаг к перегрузке операторов, благодаря которой ваши объекты будут естественно взаимодействовать со встроенными операторами Lua.
Вы организуете код в двух файлах:
Vector.lua: Определите класс Vector с компонентамиxиy. Добавьте конструктор:new(x, y)и реализуйте метаметод__add, чтобы при сложении двух векторов создавался новый вектор с суммой соответствующих компонентов. Определите__addчерез точку, чтобы оба операнда передавались как именованные аргументы.main.lua: Подключите модуль Vector, создайте экземпляры векторов и покажите, что их сложение дает правильный результат.
На вход вы получите четыре значения:
- Компонент x первого вектора
- Компонент y первого вектора
- Компонент x второго вектора
- Компонент y второго вектора
В главном файле создайте два вектора с заданными компонентами, сложите их с помощью оператора + и выведите значения x и y результирующего вектора, каждое с новой строки.
Например, если входные данные — 3, 4, 1, 2, вывод должен быть таким:
4
6Сумма первого вектора (3, 4) и второго вектора (1, 2) равна новому вектору (4, 6).
Попробуйте сами
-- Подключить модуль Vector
local Vector = require('Vector')
-- Считать входные данные
local x1 = tonumber(io.read())
local y1 = tonumber(io.read())
local x2 = tonumber(io.read())
local y2 = tonumber(io.read())
-- TODO: Создать два экземпляра Vector, используя входные значения
-- TODO: Сложить два вектора с помощью оператора +
-- TODO: Вывести значения x и y результирующего вектора на отдельных строках
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Концепция 'self'
Таблицы с функциямиЯвный 'self'Синтаксис с двоеточиемТочка против двоеточияИтоги — Движущаяся точка4Проект: Цифровой банк
Настройка проектаМетод пополнения7Полиморфизм и переопределение
Переопределение методовВызов родительских методовУтиная типизацияОбщий интерфейсПроверка типаИтоги — Роли сотрудников2Паттерн прототипа класса
Концепция прототипаСвязывание через __indexКонструктор :new()Инициализация атрибутовНезависимые экземплярыИтоги — Автозавод5Перегрузка операторов в ООП
Сложение объектовВычитание объектовКонкатенация объектовСравнение объектов (<, >)Повторение — Математика кошелька8Инкапсуляция
Соглашения об именованииЗамыкания для приватностиДоступ через замыканияТаблицы только для чтенияЛогика валидацииИтоги — Защищенное хранилище11Паттерны проектирования (Lite)
Фабричные функцииТаблица SingletonПаттерн IteratorObserver (Слушатель)Итоги — Logger Factory3Состояние и поведение объектов
Переменные экземпляраГеттерыСеттерыВычисляемые свойстваФорматирование строкПроверка на равенствоПовторение — Оценка студента6Основы наследования
Настройка наследованияНаследование методовРасширение конструктораДобавление дочерних методовОбщее и уникальноеИтоги: Иерархия фигурПотренируйтесь самостоятельно: Онлайн-компилятор Lua