ООП в Lua. Использование замыканий. |
Здравствуйте, гость ( Вход | Регистрация )
ООП в Lua. Использование замыканий. |
15.11.2012, 13:39
Сообщение
#1
|
|
Абсолютный новичок Группа: Пользователи Сообщений: 1 Регистрация: 29.10.2012 Из: Екатеринбург Пользователь №: 10 983 Спасибо сказали: 2 раза |
Здравствуйте, уважаемое Сообщество
Меня, как и многих других, интересуют технологии объектно-ориентированного программирования в Lua. Из литературы по Lua известен следующий пример: Раскрывающийся текст Код function anyClass(value) local function get() return value end local function set(v) value = v end return { get = get, set = set } end local x = anyClass(123) print( x.get() ) x.set(987) print( x.get() ) Все описания данного приёма программирования, которые я встретил, ограничиваются вышеописанным примером. Способы организации наследования классов мне нигде не попадались. Поэтому хочется поделиться своими. Далее будет довольно большой пример. Раскрывающийся текст Код local print = print local function Object() local PUBLIC = {} -- public, interface local VIRTUAL = {} -- protected, virtual return PUBLIC, VIRTUAL end local function Figure() -- inheritance local PUBLIC, VIRTUAL = Object() local this = VIRTUAL -- private local function CreateDC() print 'Create DC' end local function ReleaseDC() print 'Release DC\n' end local function BeginPaint() print 'Begin Paint' end local function EndPaint() print 'End Paint' end function PUBLIC.Draw() -- public method CreateDC() BeginPaint() VIRTUAL.Draw() -- virtual call EndPaint() ReleaseDC() end VIRTUAL.Draw = nil -- abstract method return PUBLIC, VIRTUAL end local function Point(x, y) local PUBLIC, VIRTUAL = Figure() local this = VIRTUAL function PUBLIC.Set(x, y) this.x = x + 0 this.y = y + 0 end PUBLIC.Set(x, y) -- initialization function PUBLIC.Get() return this.x, this.y end function VIRTUAL.Draw() print( '\tDraw Point', this.x, this.y ) end return PUBLIC, VIRTUAL end local function Text(x, y, txt) local PUBLIC, VIRTUAL = Point(x, y) local this = VIRTUAL local SUPER = { Set = PUBLIC.Set, Get = PUBLIC.Get } function PUBLIC.Set(x, y, txt) SUPER.Set(x, y) this.txt = txt .. '' end PUBLIC.Set(x, y, txt) function PUBLIC.Get() return this.x, this.y, this.txt end function VIRTUAL.Draw() print( '\tDraw Text', this.x, this.y, this.txt ) end return PUBLIC, VIRTUAL end local function Rect(x, y, w, h) local PUBLIC, VIRTUAL = Point(x, y) local this = VIRTUAL local SUPER = { Set = PUBLIC.Set, Get = PUBLIC.Get } function PUBLIC.Set(x, y, w, h) SUPER.Set(x, y) this.w = w + 0 this.h = h + 0 end PUBLIC.Set(x, y, w, h) function PUBLIC.Get() return this.x, this.y, this.w, this.h end VIRTUAL.Draw = nil return PUBLIC, VIRTUAL end local function Rectangle(x, y, w, h) local PUBLIC, VIRTUAL = Rect(x, y, w, h) local this = VIRTUAL function VIRTUAL.Draw() print( '\tDraw Rectangle', this.x, this.y, this.w, this.h ) end -- define operator function PUBLIC.__tostring() return ("{ Rectangle %d, %d, %d, %d }"):format(this.x, this.y, this.w, this.h) end setmetatable(PUBLIC, PUBLIC) return PUBLIC, VIRTUAL end local function Ellipse(x, y, w, h) local PUBLIC, VIRTUAL = Rect(x, y, w, h) local this = VIRTUAL function VIRTUAL.Draw() print( '\tDraw Ellipse', this.x, this.y, this.w, this.h ) end function VIRTUAL.__tostring() return ("{ Ellipse %d, %d, %d, %d }"):format(this.x, this.y, this.w, this.h) end setmetatable(PUBLIC, VIRTUAL) return PUBLIC, VIRTUAL end local point1 = Point(5, 99) local point2 = Point(333, 7) point1.Draw() point2.Draw() point1.Draw() local rect1 = Rectangle(2, 5, 20, 30) rect1.Draw() local rect2 = Rectangle(100, 100, 100, 100) rect2.Draw() rect1.Draw() rect1.Set(1, 1, 1, 1) rect1.Draw() print(rect1, '\n') print(rect1.__tostring(), '\n') local ell1 = Ellipse(33, 44, 55, 66) ell1.Draw() print( ell1, '\n' ) local text1 = Text(400, 200, 'Aaaaaaaaaaaaaaaaaaaaaa') local text2 = Text(4, 5, 'Bbbbbbbbbbbbbbbbbbbbbb') text1.Draw() text2.Draw() text2.Set(333, 333, '**********************') text2.Draw() Как видно из примера, при помощи замыканий можно создавать нечто очень близкое к классическому ООП. В следующем примере показано создание внутреннего класса, как именованного, так и анонимного. Оба класса имеют доступ к полям и методам содержащего их класса. Прямо Java . Раскрывающийся текст Код function Object() local PUBLIC = {} local VIRTUAL = {} return PUBLIC, VIRTUAL end function Iterator()local PUBLIC,VIRTUAL=Object() function PUBLIC.Iterate() VIRTUAL.First() while VIRTUAL.Next() do VIRTUAL.Exec() end end return PUBLIC,VIRTUAL end -- Пример с обычным классом-наследником function MyIterator()local PUBLIC,VIRTUAL=Iterator() local array = { 2, 4, 3, 9, 6 } local pos = 0; function VIRTUAL.First() pos = 0 end function VIRTUAL.Next() pos = pos + 1 return pos <= #array end function VIRTUAL.Exec() print(pos, array[pos]) end return PUBLIC,VIRTUAL end --[[ local iter = MyIterator() iter.Iterate() --]] -- Пример с внутренними классами function Test()local PUBLIC,VIRTUAL=Object() local array = { 89, 32.74, 892, 64.000001, 3488, 9, 589, 534 } local pos = 0 -- Внутренний класс local function Iterator1()local PUBLIC,VIRTUAL=Iterator() function VIRTUAL.First() pos = 0 end function VIRTUAL.Next() pos = pos + 1 return pos <= #array end function VIRTUAL.Exec() print('Test1', pos, array[pos]) end return PUBLIC,VIRTUAL end function PUBLIC.Test1() print '{1}' local iter = Iterator1() iter.Iterate() end -- Анонимный внутренний класс do local object,class = Iterator() function class.First() pos = #array + 1 end function class.Next() pos = pos - 1 return pos >= 1 end function class.Exec() print('Test2', pos, array[pos]) end function PUBLIC.Test2() print '{2}' object.Iterate() end end -- return PUBLIC,VIRTUAL end local test = Test() test.Test1() test.Test2() Буду рад, если вышеописанное кому-нибудь пригодится. |
|
|
23.4.2013, 15:36
Сообщение
#2
|
|
Абсолютный новичок Группа: Пользователи Сообщений: 1 Регистрация: 23.4.2013 Пользователь №: 11 474 Спасибо сказали: 0 раз |
|
|
|
Похожие темы
Тема | Ответов | Автор | Просмотров | Последнее сообщение | |
---|---|---|---|---|---|
От: ООП в Lua. Использование замыканий. От темы с ID: 5362 |
0 | Saymon21 | 4 440 | 15.11.2012, 14:08 Посл. сообщение: Saymon21 | |
[RusHub] Использование posix capabilities Linux ONLY |
9 | ShadoWx | 14 048 | 1.2.2012, 22:46 Посл. сообщение: mariner | |
Использование Прокси И Защита От Прокси... "околопроксёвые" вопросы |
0 | dimetrius | 6 911 | 15.7.2008, 19:16 Посл. сообщение: dimetrius |
|
Сейчас: 23.12.2024, 4:49 |