OO в Lua
Прежде всего, следует отметить, что Lua не реализует объектно-ориентированное программирование;в нем нет понятия объектов, классов, наследования и т. д.
Если вы хотите, чтобы ООП в Lua, вы должны реализовать это самостоятельно.Обычно это делается путем создания таблицы, которая действует как «класс», сохраняя «методы экземпляра», которые на самом деле являются просто функциями, которые принимают экземпляр в качестве первого аргумента.
Затем наследование достигается наличием«Конструктор» (также просто функция) создает новую таблицу и устанавливает для нее метатабельность с полем __index
, указывающим на таблицу классов.При индексации «экземпляра» по ключу, которого у него нет, он вместо этого будет искать этот ключ в классе.
Другими словами, таблица «экземпляра» может вообще не иметь функций, ноиндексируя его, например, с помощью "withdraw"
, просто попробуйте вместо этого индексировать класс.
Теперь, если мы возьмем одну таблицу «instance» и добавим к ней поле withdraw
, Lua увидит, что онаимеет это поле и не надо искать его в классе.Можно сказать, что это значение shadows значение в таблице классов.
Как называется эта "техника"
Это недействительно есть, но вы обязательно должны посмотреть метатаблицы.
На языках, которые делают , поддерживают такие вещи, как в Ruby (см. ниже), это часто делается с одноэлементными классами, что означаетчто они имеют только один экземпляр.
Замечания по производительности
Таблицы индексирования, включая метатаблицы, занимают некоторое время.Если Lua находит метод в таблице экземпляров, то это поиск по одной таблице;если этого не произойдет, то сначала нужно получить метатаблицу и индексировать ее, а если у нее этого тоже нет, и у нее есть своя метатабельность, цепочка будет продолжаться следующим образом.
Итак, вдругими словами, это на самом деле быстрее .Он занимает немного больше места, но не так много ( технически это может быть довольно много, но вам не стоит об этом беспокоиться. Тем не менее, здесь вы можете прочитать очто , если хотите).
Какие-либо другие oo языки программирования с такой возможностью?
Да, их много.Ruby - хороший пример, где вы можете сделать что-то вроде
array1 = [1, 2, 3]
array2 = [4, 5, 6]
def array1.foo
puts 'bar'
end
array1.foo # prints 'bar'
array2.foo # raises `NoMethodError`