|
Здравствуйте, гость ( Вход | Регистрация )
![]() ![]() |
|
![]() ![]()
Сообщение
#1
|
|
![]() RusHub team lead ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Модераторы Сообщений: 4 030 Регистрация: 20.6.2008 Из: г. Королёв (Моск. обл.) Пользователь №: 46 Спасибо сказали: 1708 раз ![]() |
Продолжаю знакомство с ООП в LUA.
Реализация класса в lua.
Код --//Функция-конструктор класса cMyClass cMyClass = function(tData) local t = {} tData = tData or {} --//private: t.z = 0 --//Значение по умолчанию t.PrivateFunc = function() return "Это закрытая функция, которая доступна только внутри данного класса cMyClass!" end --//public: tData.x = tData.x or 0 tData.y = tData.y or 0 --//Инициализация полей 'x' и 'y' t.__call = function(f, a, b) if a then tData.x = a end if b then tData.y = b end end --//Получения значения индекса t.__index = function(tab, key) if key == "z" then --//Защита от чтения 'private' переменной 'z' return elseif key == "GetZ" then --//Объявление 'public' функции, которая возвращает значание 'private' переменной 'z' return function() return t.z end elseif key == "SetZ" then --//Объявление 'public' функции, которая записывает значание в 'private' переменную 'z' return function(z) t.z = z return true end elseif key == "x" then --//Доступ к 'public' полю 'x' return tData.x or 0 elseif key == "y" then --//Доступ к 'public' полю 'y' return tData.y or 0 elseif rawget(tab, key) then --//Доступ к любому другому 'public' полю return rawget(tab, key) end end --//Присвоение новому индексу значения t.__newindex = function(tab, key, val) if key == "z" then --//Защита от записи в 'private' переменную 'z' return else --//Запись в любое другое поле return rawset(tab, key, val) end end setmetatable(tData, t) return tData end Использование класса cMyClass Код --//Создаём объект 'u' типа 'cMyClass' с 'public' полем 'z'
local u = cMyClass({z="u.z_value"}) --//Создаём объект 'v' типа 'cMyClass' с 'public' полями 'x' и 'y' local v = cMyClass({x="v.x_value",y="v.y_value"}) --//Инициализируем 'public' поля 'x' и 'y' объекта 'u' u("u.x_value", "u.y_value") --//Устанавливаем значение 'private' поля 'z' объекта 'u' u.SetZ("private_z_value") --//Выводим результаты Core.SendToAll("\n==============================================\n\t".. "u.x = '"..tostring(u.x).."', \tv.x = '"..tostring(v.x).."';\n\t".. "u.y = '"..tostring(u.y).."', \tv.y = '"..tostring(v.y).."';\n\t".. "u.z = '"..tostring(u.z).."', \tv.z = '"..tostring(v.z).."';\n\t".. "u.GetZ() = '"..tostring(u.GetZ()).."', \tv.GetZ() = '"..tostring(v.GetZ()).."'.\n".. "==============================================") |
|
|
![]()
Сообщение
#2
|
|
![]() RusHub team lead ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Модераторы Сообщений: 4 030 Регистрация: 20.6.2008 Из: г. Королёв (Моск. обл.) Пользователь №: 46 Спасибо сказали: 1708 раз ![]() |
Универсальная функция для создания класса в lua.
Включает в себя аппарат простого и множественного наследования. Для множественного наследования используется несколько раз простое наследование. Код local function concat(p1, p2) local t = {} for k, v in pairs(p1) do t[k] = v end for k, v in pairs(p2) do t[k] = v end if next(p1.__parent or {}) or next(p2.__parent or {}) then t.__parent = concat(p1.__parent or {}, p2.__parent or {}) end return t end class = function(...) local t, m = {}, {} _G.setmetatable(t, m) for i = 1, _G.select('#', ...) do local el = _G.select(i, ...) if _G.type(el) == 'table' then for k, v in _G.pairs(el) do t[k] = v end end end t.__parent = m m.__call = function(self, ...) local t, mt_old, mt_new = {}, {}, {} for k, v in pairs(getmetatable(self) or {}) do mt_old[k] = v end for k, v in pairs(self) do mt_old[k] = v end for i = 1, _G.select('#', ...) do local el = _G.select(i, ...) if _G.type(el) == 'table' then for k, v in pairs(getmetatable(el) or {}) do mt_new[k] = v end for k, v in _G.pairs(el) do t[k] = v end end end mt_new = concat(mt_old, mt_new) mt_new.__index = mt_new t.__parent = mt_new _G.setmetatable(t, mt_new) return t end return t end Объявляем классы Код A = class{ f1 = function() Core.SendToAll"A.f1" end; } B = A{ f1 = function() Core.SendToAll"B.f1" end; f2 = function() Core.SendToAll"B.f2" end; } C = class{ f2 = function() Core.SendToAll"C.f2" end; f3 = function() Core.SendToAll"C.f3" end; } D = B{ f1 = function() Core.SendToAll"D.f1" end; f2 = function() Core.SendToAll"D.f2" end; f3 = function() Core.SendToAll"D.f3" end; } D = C(D) -- реализация множественного наследования Структура наследования такова: * класс A - базовый класс * класс B - наследует класс A * класс С - базовый класс * класс D - наследует классы B и С (множественное наследование) Вызов функций классов: Код Core.SendToAll"\t\tВызываем в каждом классе свои функции:" Core.SendToAll"\tКласс A" A.f1() Core.SendToAll"\tКласс B" B.f1() B.f2() Core.SendToAll"\tКласс C" C.f2() C.f3() Core.SendToAll"\tКласс D" D.f3() D.f3() D.f3() Core.SendToAll"\t\tВызываем в классе D унаследованные функции:" D.__parent.__parent.f1() D.__parent.f1() D.__parent.f2() D.__parent.f3() Что выводится на экран: Цитата Вызываем в каждом классе свои функции:
Класс A A.f1 Класс B B.f1 B.f2 Класс C C.f2 C.f3 Класс D D.f3 D.f3 D.f3 Вызываем в классе D унаследованные функции: A.f1 B.f1 B.f2 C.f3 |
|
|
![]()
Сообщение
#3
|
|
![]() Самый главный активист :-D ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Модераторы Сообщений: 2 790 Регистрация: 29.6.2008 Из: г. Тула Пользователь №: 97 Спасибо сказали: 440 раз ![]() |
чем больше пытаюсь разобраться тем больше путаюсь. предположительный ответ
Цитата first_class_mMember2 2Setuper: Илюх если ответ не правильный то напиши что неправильно я буду пробовать дальше сам(ответ не пиши)!!! |
|
|
![]()
Сообщение
#4
|
|
![]() RusHub team lead ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Модераторы Сообщений: 4 030 Регистрация: 20.6.2008 Из: г. Королёв (Моск. обл.) Пользователь №: 46 Спасибо сказали: 1708 раз ![]() |
Неправильный
Вот пример для проверки Код cMyFirstClass = cClass{ mMember1 = 5; mMember2 = "first_class_mMember2"; func1 = function(self) Core.SendToAll(self.mMember2) end func2 = function(self) Core.SendToAll"Example" end } cMySecondClass = cMyFirstClass{ mMember2 = "second_class_mMember2"; func3 = function(self) self:func2() end } cMySecondClass:func1() Просто нужно понять что такое наследование. |
|
|
![]() ![]()
Сообщение
#5
|
|
![]() RusHub team lead ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Модераторы Сообщений: 4 030 Регистрация: 20.6.2008 Из: г. Королёв (Моск. обл.) Пользователь №: 46 Спасибо сказали: 1708 раз ![]() |
Описание класса с функциями "необязательного объявления".
Суть функций "необязательного объявления": при модульном написании проектов, иногда существует потребность в отключении некоторых функций. Эта потребность связана с варьированием функционала проекта в зависимости от потребностей пользователей. Предлагаемое описание класса позволяет даже не загружать модули с объявлениями функций, но тем не менее использовать вызовы этих функций. Не объявленные функции будут выполняться как функции-заглушки, то есть не будут ничего делать и будут возвращать значение nil. На этапе отладки работы с модулями рекомендуется создать функцию логирования загрузок всех модулей, дабы понять какой модуль не был загружен, и следовательно функции какого модуля были заменены на функции-заглушки. Код --[[
* * Copyright (C) 2009 by Setuper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 3 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. ]] --[[ Module for building of classes with inheritance * Returns function for building of the class * * class(...) * * @author Setuper ]] do local _G = _G local function concat(p1, p2) local t = {} for k, v in _G.pairs(p1) do t[k] = v end for k, v in _G.pairs(p2) do t[k] = v end if _G.next(p1.__parent or {}) or _G.next(p2.__parent or {}) then t.__parent = concat(p1.__parent or {}, p2.__parent or {}) end return t end class = function(...) local t, m = {}, {} _G.setmetatable(t, m) for i = 1, _G.select('#', ...) do local p = _G.select(i, ...) if _G.type(p) == "table" then for k, v in _G.pairs(p) do t[k] = v end end end m.__call = function(self, ...) local t, mt_old, mt_new = {}, {}, {} for k, v in _G.pairs(_G.getmetatable(self) or {}) do mt_old[k] = v end for k, v in _G.pairs(self) do mt_old[k] = v end for i = 1, _G.select('#', ...) do local p = _G.select(i, ...) if _G.type(p) == "table" then for k, v in _G.pairs(_G.getmetatable(p) or {}) do mt_new[k] = v end for k, v in _G.pairs(p) do t[k] = v end end end mt_new = concat(mt_old, mt_new) mt_new.__index = function(self, key) if t.__parent[key] then return t.__parent[key] else return function(self) return nil end end end t.__parent = mt_new _G.setmetatable(t, mt_new) return t end return t end end |
|
|
![]() ![]()
Сообщение
#6
|
|
![]() RusHub team lead ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Модераторы Сообщений: 4 030 Регистрация: 20.6.2008 Из: г. Королёв (Моск. обл.) Пользователь №: 46 Спасибо сказали: 1708 раз ![]() |
Простой пример скрипта RegCmd на использование классов.
Содержит наглядные примеры использования в lua:
Не содержит наглядных примеров на использование аппаратов наследования и полиморфизма (рассмотрено ранее). ![]() |
|
|
![]() ![]() |
Похожие темы
Тема | Ответов | Автор | Просмотров | Последнее сообщение | |
---|---|---|---|---|---|
![]() |
![]() Создание и использование классов |
9 | Setuper | 33 626 | 1.7.2016, 9:24 Посл. сообщение: MIKHAIL |
![]() |
Сейчас: 8.9.2024, 2:46 |