Прототипное ООП для Lua

Привет, я придумал свой велосипед для реализации прототипного подхода ООП в Lua.Основные фишки

Single inheritance Traits LuaJIT Перейдем сразу к примерам.

 — подключаем модуль local object = require («object»)

-- определяем наш класс, который на самом деле объект local HelloClass = object: extend (function (class)  — конструктор (необязательно) function class: init (name) self.name = name end

 — метод класса function class: sayHello () print («Hello » … self.name) end end)

local hello = HelloClass: new («John») hello: sayHello () Как видим, вся магия заключается в методе extend (traits…, f), который расширяет текущий объект.Можно определять переменные внутри

local object = require («object») local Status = object: extend (function (status) status.HTTP_200_OK = {200, «OK»} status.HTTP_405_METHOD_NOT_ALLOWED = {404, «Method not allowed»} end)

print (Status.HTTP_200_OK[2]) Статические методы Куда же без них… local object = require («object») local MathUtils = object: extend (function (class) function class.square (x) return x * x end end)

-- вызываем статический метод print (MathUtils.square (10))

-- вызывает тот же метод, но уже через инстанс print (MathUtils: new ().square (10)) — 100 Конструктор При создании нового экземпляра через new () вызывается конструктор init () local Counter = object: extend (function (class)  — конструктор, который принимает какой-то параметр (может быть много параметров) function class: init (initial) self.ticks = initial or 0 end

function class: tick () self.ticks = self.ticks + 1 end

function class: getTicks () return self.ticks end end)

local c = Counter: new () c.tick () c.tick () print (c: getTicks () == 2) Наследование и перегрузка методов Как я упомянул, наследование сделано как single inheritance, то есть отнаследоваться можно только от одного «класса», однако есть еще трейты, о которых поговорим чуть позже. Перегрузка методов не вызывает никаких вопросов. local Shape = object: extend (function (class) function class: getArea () return 0 end end)

local Square = Shape: extend (function (class) function class: init (side) self.side = side end

 — перегружаем метод function class: getArea () return self.side * self.side end end)

local sq = Square: new (10) print («Area = » … sq: getArea ()) Вызов родительского метода Для этого надо использовать второй параметр лямбда-функции, которую передаете в extend, которая есть ссылка на родительский объект (который хотим расширить) local Foo = object: extend (function (class) function class: init (value) self.value = value end

function class: say () print («Hello » … self.value) end end)

class Bar = Foo: extend (function (class, parent) function class: init (value)  — вызывает конструктор родителя parent.init (self, value) end end)

local foo = Foo: new («World») foo: say () — напечатает «Hello World»

local bar = Bar: new («World») bar: say () — напечатает «Hello World» Трейты Когда не хватает множественного наследования как в С++, можете воспользоваться трейтами, которые расширяют функционал.Просто передайте ваши трейты в начало аргументов extend ()

local TraitX = function (trait) function trait: setX (x) self.x = x return self end function trait: getX () return self.x end end

local A = object: extend (TraitX, function (class) function class: say () print (self.x) end end)

A: new (): setX (10): say () Полезные функции is_instanceof (self, instance) — вернет true, если instance является прямым или непрямым наследником self local ClassA = object: extend () local ClassB = object: extend ()

local obj_a = ClassA: new () local obj_b = ClassB: new ()

print (obj_a: is_instanceof (ClassA)) — true print (obj_a: is_instanceof (object)) — true print (obj_a: is_instanceof (ClassB)) — false is_typeof (self, instance) — вернет true, если instance является прямым наследником self

local ClassA = object: extend () local ClassB = object: extend ()

local obj_a = ClassA: new () local obj_b = ClassB: new ()

print (obj_b: is_typeof (ClassA)) — false print (obj_b: is_typeof (ClassB)) — true LuaJIT Как альтернатива, поддерживается работа в LuaJIT.Где код, Карл? Здесь

© Habrahabr.ru