yosefk.com/c++fqa/class.html

нет встроенной поддержки OO, но она позволяет вам создавать ее самостоятельно. Не могли бы вы поделиться некоторыми способами реализации ОО?

Пожалуйста, напишите один пример за ответ. Если у вас есть еще примеры, опубликуйте другой ответ.

 Łukasz Gruner25 янв. 2011 г., 22:37
Я добавлю к нему награду, как только выясню, как, так что главный ответ, скажем, «примерно в неделю», получит :)
 Ashley Davies05 февр. 2011 г., 16:47
У Lua's PIL есть подробные ссылкиlua.org/pil/16.html
 jar19 дек. 2016 г., 16:59
Вот своего рода шаблон для быстрого начала работы с ООП в Luaalbertech.blogspot.com/2016/12/...
 Kevin Vermeer23 мая 2012 г., 16:25
Lua Users Wiki имеет большой набор ресурсов о способах реализации ООП в Lua. Есть множество способов; Вы можете использовать таблицы, метатаблицы, прокси-таблицы или замыкания. Также доступны библиотеки, такие как LOOP и ObjectLua, но очень легко написать свою собственную или скопировать в эталонный дизайн.
 Lee Louviere25 янв. 2011 г., 22:37
Вы имеете в виду как C ++? Ну, лучше не вступать в эту дискуссию :(

Ответы на вопрос(5)

Для быстрой и грязной реализации я делаю что-то вроде -

function newRGB(r,g,b)
  return {
    red=r;
    green=g;
    blue=b;
    name='';
    setName = function(self,name)
      self.name=name;
    end;
    getName = function(self)
      return self.name;
    end;
    tostring = function(self)
      return self.name..' = {'..self.red..','..self.green..','..self.blue..'}'
    end
  }
end

который затем может быть использован как -

blue = newRGB(0,0,255);
blue:setName('blue');

yellow = newRGB(255,255,0);
yellow:setName('yellow');

print(yellow:tostring());
print(blue:tostring());

для более полнофункционального подхода я бы использовал библиотеку oo, как было упомянуто eemrevnivek. Вы также можете найти простую функцию классаВот что-то среднее между библиотекой и быстрым и грязным.

 Nasser04 июл. 2016 г., 12:24
лучшее и простое решение, которое я видел.
Решение Вопроса

что ООП - это инкапсуляция данных внутри контейнера (объекта) в сочетании с подмножеством операций, которые можно выполнить с этими данными. Это намного больше, но давайте предположим, что это простое определение - это все и создадим что-то на Lua из него (также некоторое знакомство с другими реализациями ОО может быть хорошим стимулом для читателя).

Любой, кто мало знаком с Lua, может знать, что таблицы - это отличный способ хранить пары ключ-значение, и в сочетании со строками вещи начинают становиться очень интересными:

local obj = {} -- a new table
obj["name"] = "John"
obj["age"] = 20
-- but there's a shortcut!
print("A person: " .. obj.name .. " of the age " .. obj.age)

Доступ к строковым значениям в качестве ключей в таблице может быть получен очень похожим образом на элементы структуры в C или открытые члены объекта в C ++ / Java и аналогичных языках.

А теперь крутой фокус: давайте объединим это с анонимными функциями.

-- assume the obj from last example
obj.hello = function () 
   print("Hello!")
end

obj.goodbye = function ()
   print("I must be going.")
end

obj.hello()
obj.goodbye()

Круто верно? Теперь у нас есть средства для хранения функций внутри наших таблиц, и снова вы можете видеть, что это похоже на то, как методы используются в других языках ООП. Но чего-то не хватает. Как мы можем получить доступ к данным, которые принадлежат нашему объекту в наших определениях методов? Обычно это решается путем изменения сигнатуры функций в таблице примерно так:

-- assume the obj from last example
obj.inspect = function (self)
   print("A person: " .. self.name .. " of the age " .. self.age)
end

obj.hello = function (self) 
   print(self.name .. ": Hello! I'm " .. self.name)
end

obj.goodbye = function (self)
   print(self.name .. ": I must be going.")
end

-- now it receives the calling object as the first parameter
obj.inspect(obj) -- A person: John of age 20
obj.hello(obj) -- John: Hello! I'm John
obj.goodbye(obj) -- John: I must be going

Это решает это простым способом. Возможно, проведя параллель с тем, как все работает в Python (методы всегда получают явное «я»), вы можете узнать, как это работает в Lua. Но, парень, разве не неудобно явно передавать все эти объекты в вызовах наших методов? Да, это меня тоже беспокоит, так что есть еще один способ помочь вам в использовании ООП:

obj:hello() -- is the same as obj.hello(obj)

Наконец, я только что поцарапал поверхность того, как это можно сделать. Как было отмечено вКомментарий Кевина Вермеера,Lua Users Wiki является отличным источником информации по этой теме, и там вы можете узнать все о том, как реализовать другие важные аспекты ООП, которые были проигнорированы в этом ответе (частные члены, как создавать объекты, наследование, ...). Имейте в виду, что такой способ работы является небольшой частью философии Lua, предоставляя вам простые ортогональные инструменты, способные создавать более сложные конструкции.

 Nasser04 июл. 2016 г., 10:46
I like to think of OOP as being the encapsulation of data inside a container (the Object) coupled with a subset of operations that can be done with this data Обычно это называется объектно-ориентированным, поскольку это не полный ООП. Иногда также называется ADT (абстрактные типы данных). ADT проще в обращении и может быть реализован практически на любом языке, кроме отсутствия наследования, в нем есть все, что нужно.
 fouronnes03 февр. 2011 г., 16:09
Хороший ответ. Я бы добавил, что вы можете написатьfunction obj:hello() **stuff here** end вместоobj.hello = function(self) **stuff here** end, что выглядит еще приятнее!

которое я видел, - не реализовывать OO в Lua, где оно не является естественным и неоднородным и, следовательно, занимает много строк; скорее, реализуйте это на C ++, используя luabridge или luabind, где это естественно и мощно!

Минималистичный пример, который использует LuaBridge:

m.class_<MyClass>("MyClass")
.constructor<void (*) (/* parameter types */)>()
.method("method1", &MyClass::method1)
.property_rw("property2", &MyClass::getter2, &MyClass::setter2)
.property_ro("property3", &MyClass::property3)

Это переведет на естественный синтаксис lua:

c=MyClass()
c.method1()
c.property2 = c.property3 * 2
do_stuff(c.property3)

Также поддерживается одноуровневое наследование ...

 lfzawacki05 февр. 2011 г., 05:49
ИМХО, было бы излишне включать C ++ в проект lua для получения ООП. Некоторые люди утверждают (включая меня), что ООП C ++ на самом деле очень замысловатый, сложный и не совсем верный исходным принципам ООП. Кроме того, программист должен был бы знать другой язык, чтобы использовать его, не очень хорошо ... вот хорошее прочтение на C ++ и его реализации OOyosefk.com/c++fqa/class.html

class = {} -- Will remain empty as class
mt = {} -- Will contain everything the instances will contain _by default_

mt.new = function(self,foo)
    local inst={}
    if type(foo) == "table" then
         for k,v in pairs(foo) do
             inst[k]=v
         end
    else
        inst.foo=foo
    end
    return setmetatable(inst,getmetatable(class))
end

mt.print = function(self)
    print("My foo is ",self.foo)
end

mt.foo= 4 --standard foo

mt.__index=mt -- Look up all inexistent indices in the metatable

setmetatable(class,mt)

i1=class:new() -- use default foo
i1:print()

i2=class:new(42)
i2:print()

i3=class:new{foo=123,print=function(self) print("Fancy printing my foo:",self.foo) end}

Итак, вывод: с метатаблями и некоторым умным мышлением возможно всё: метатаблы - РЕАЛЬНАЯ магия при работе с классами.

средний класс.

Эта библиотека обеспечивает необходимый минимум для создания классов, экземпляров, наследования, полиморфизма и (примитивных) миксинов с приемлемой производительностью.

Образец:

local class = require 'middleclass'

local Person = class('Person')

function Person:initialize(name)
  self.name = name
end
function Person:speak()
  print('Hi, I am ' .. self.name ..'.')
end

local AgedPerson = class('AgedPerson', Person) -- or Person:subclass('AgedPerson')

AgedPerson.static.ADULT_AGE = 18 --this is a class variable
function AgedPerson:initialize(name, age)
  Person.initialize(self, name) -- this calls the parent's constructor (Person.initialize) on self
  self.age = age
end
function AgedPerson:speak()
  Person.speak(self) -- prints "Hi, I am xx."
  if(self.age < AgedPerson.ADULT_AGE) then --accessing a class variable from an instance method
    print('I am underaged.')
  else
    print('I am an adult.')
  end
end

local p1 = AgedPerson:new('Billy the Kid', 13) -- this is equivalent to AgedPerson('Billy the Kid', 13) - the :new part is implicit
local p2 = AgedPerson:new('Luke Skywalker', 21)
p1:speak()
p2:speak()

Выход:

Hi, I am Billy the Kid.
I am underaged.
Hi, I am Luke Skywalker.
I am an adult.

Ваш ответ на вопрос