Skip to content

Commit d1e461c

Browse files
authored
Merge pull request #1 from lodsdev/dev
New version 2.0
2 parents 91ee113 + ece846e commit d1e461c

File tree

4 files changed

+190
-128
lines changed

4 files changed

+190
-128
lines changed

README.md

Lines changed: 48 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,11 @@ class 'Animal' {
4747
end
4848
}
4949

50-
class 'Dog' (extends 'Animal' {
50+
class 'Dog' : extends 'Animal' {
5151
constructor = function(self, name)
5252
self.name = name
5353
end
54-
})
54+
}
5555

5656
local dog = new 'Dog'('Bob')
5757
dog:eat() -- Eating...
@@ -74,61 +74,69 @@ class 'Animal' {
7474
end
7575
}
7676

77-
class 'Dog' (extends 'Animal' {
77+
class 'Dog' : extends 'Animal' {
7878
constructor = function(self, name)
7979
self.name = name
8080
end,
8181

8282
speak = function(self)
8383
print('Woof! My name is ' .. self.name .. '.')
8484
end
85-
})
85+
}
8686
```
8787

88+
## Interfaces
89+
90+
The **Lua Class** library als supports interface concepts. An interface is a blueprint of a class that defines the methods and attributes that a class must implement. A class can implement multiple interfaces and must implement all the methods and attributes defined in the interfaces it implements.
8891

89-
### Method overloading
92+
To create an interface, simply call the `interface` function and pass the interface name and table containing the methods attributes of the interface as arguments. For example:
9093

91-
The **Lua Class** library also supports method overloading. This means that a class can have multiple methods with the same name, but with different parameters. To overload a method, simply call the `self.overload` function and pass a table containing the different implementations of the method as arguments, but the index of the table must be the number of parameters of the method. For example:
94+
```lua
95+
interface 'telePhone' {
96+
'call',
97+
'sendSMS',
98+
'receiveSMS'
99+
}
100+
```
101+
To make a class implement an interface, simply pass the interface name as an argument to the `implements` function. For example:
92102

93103
```lua
94-
class 'Calculator' {
95-
constructor = function(self)
104+
class 'SmartPhone' : implements 'telePhone' {
105+
constructor = function(self, number)
106+
self.number = number
107+
end,
108+
109+
call = function(self, number)
110+
print('Calling ' .. number .. ' from ' .. self.number .. '...')
111+
end,
112+
113+
sendSMS = function(self, number, message)
114+
print('Sending SMS to ' .. number .. ' from ' .. self.number .. '...')
96115
end,
97116

98-
add = function(self, ...)
99-
self.overload ({
100-
[2] = function(self, a, b)
101-
return a + b
102-
end,
103-
[3] = function(self, a, b, c)
104-
return a + b + c
105-
end
106-
}, ...)
117+
receiveSMS = function(self, number, message)
118+
print('Received SMS from ' .. number .. ' to ' .. self.number .. '...')
107119
end
108120
}
109-
110-
local calc = new 'Calculator'()
111-
calc:add(1, 2) -- 3
112-
calc:add(1, 2, 3) -- 6
113121
```
114122

115-
## Interfaces
123+
### Multiple interfaces
116124

117-
The **Lua Class** library als supports interface concepts. An interface is a blueprint of a class that defines the methods and attributes that a class must implement. A class can implement multiple interfaces and must implement all the methods and attributes defined in the interfaces it implements.
118-
119-
To create an interface, simply call the `interface` function and pass the interface name and table containing the methods attributes of the interface as arguments. For example:
125+
The **Lua Class** library also supports multiple interfaces. This means that a class can implement multiple interfaces. To make a class implement multiple interfaces, simply pass the interface names as arguments to the `implements` function. For example:
120126

121127
```lua
122128
interface 'telePhone' {
123129
'call',
124130
'sendSMS',
125131
'receiveSMS'
126132
}
127-
```
128-
To make a class implement an interface, simply pass the interface name as an argument to the `implements` function. For example:
129133

130-
```lua
131-
class 'SmartPhone' (implements 'telePhone' {
134+
interface 'smartPhone' {
135+
'touchScreen',
136+
'internet'
137+
}
138+
139+
class 'SmartPhone' : implements ('telePhone', 'smartPhone') {
132140
constructor = function(self, number)
133141
self.number = number
134142
end,
@@ -143,8 +151,16 @@ class 'SmartPhone' (implements 'telePhone' {
143151

144152
receiveSMS = function(self, number, message)
145153
print('Received SMS from ' .. number .. ' to ' .. self.number .. '...')
154+
end,
155+
156+
touchScreen = function(self)
157+
print('Touching screen...')
158+
end,
159+
160+
internet = function(self)
161+
print('Accessing internet...')
146162
end
147-
})
163+
}
148164
```
149165

150166
## Inheritance of interfaces
@@ -158,10 +174,10 @@ interface 'telePhone' {
158174
'receiveSMS'
159175
}
160176

161-
interface 'smartPhone' (extends 'telePhone' {
177+
interface 'smartPhone' : extends 'telePhone' {
162178
'touchScreen',
163179
'internet'
164-
})
180+
}
165181
```
166182

167183
## instanceof

class-oop.lua

Lines changed: 115 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -1,140 +1,161 @@
11
--[[
22
Author: https://github.com/lodsdev
3-
Version: 1.0
4-
5-
MIT License
6-
7-
Copyright (c) 2012-2022 Scott Chacon and others
8-
9-
Permission is hereby granted, free of charge, to any person obtaining
10-
a copy of this software and associated documentation files (the
11-
"Software"), to deal in the Software without restriction, including
12-
without limitation the rights to use, copy, modify, merge, publish,
13-
distribute, sublicense, and/or sell copies of the Software, and to
14-
permit persons to whom the Software is furnished to do so, subject to
15-
the following conditions:
16-
17-
The above copyright notice and this permission notice shall be
18-
included in all copies or substantial portions of the Software.
19-
20-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23-
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24-
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25-
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
3+
Version: 2.0.0
274
]]
285

29-
306
local classes = {}
317
local interfaces = {}
328

33-
local function tblCopy(t, mt)
34-
local t2 = {}
9+
local function table_copy(t)
10+
local newTbl = {}
3511
for i, v in pairs(t) do
36-
if (not t2[i]) then
37-
t2[i] = v
12+
if (not newTbl[i]) then
13+
newTbl[i] = v
3814
end
3915
end
40-
if (mt) then
41-
t2.super = mt
42-
setmetatable(t2, { __index = t2.super.array })
16+
return newTbl
17+
end
18+
19+
local function table_implements(t, t2)
20+
local newTbl = {}
21+
for k, v in ipairs(t2) do
22+
t[#t+1] = v
4323
end
44-
return t2
24+
newTbl = table_copy(t)
25+
return newTbl
4526
end
4627

47-
function class(className)
48-
return function(tbl, super)
49-
local class = classes[className]
50-
if (not class) then
51-
if (super) then
52-
super._name = super.name
53-
end
54-
tbl._name = className
55-
classes[className] = { name = className, array = tbl, super = super }
56-
end
57-
return tbl
28+
local function createClass(className, structure, superClass)
29+
if (classes[className]) then
30+
error('Class ' .. className .. ' already exists.', 2)
5831
end
32+
33+
local newClass = structure
34+
newClass.__name = className
35+
36+
if (superClass) then
37+
newClass.super = superClass
38+
setmetatable(newClass, { __index = newClass.super })
39+
end
40+
41+
classes[className] = newClass
42+
return newClass
5943
end
6044

61-
function new(className)
62-
return function(...)
63-
local classe = classes[className]
64-
if (not classe) then error('Class ' .. className .. ' not found') end
45+
function interface(interfaceName)
46+
local newInterface = {}
6547

66-
local super = (classe.super and classe.super or false)
67-
local obj = tblCopy(classe.array, (super and super or false))
48+
setmetatable(newInterface, {
49+
__call = function(self, ...)
50+
if (interfaces[interfaceName]) then
51+
error('Interface ' .. interfaceName .. ' already exists.', 2)
52+
end
6853

69-
obj.overload = function(tbl, ...)
70-
local args = {...}
71-
local func = tbl[#args]
72-
func(obj, ...)
54+
local newInstance = ...
55+
interfaces[interfaceName] = newInstance
56+
return newInstance
7357
end
58+
})
7459

75-
if (obj.constructor) then
76-
obj:constructor(...)
60+
newInterface.extends = function(self, superInterfaceName)
61+
return function(subInterface)
62+
local superInterface = interfaces[superInterfaceName]
63+
local newInstance = table_implements(subInterface, superInterface)
64+
65+
if (interfaces[interfaceName]) then
66+
error('Interface ' .. interfaceName .. ' already exists.', 2)
67+
end
68+
69+
interfaces[interfaceName] = newInstance
70+
return newInstance
7771
end
78-
return obj
7972
end
73+
74+
return newInterface
8075
end
8176

82-
function extends(superObjName)
83-
return function(tbl)
84-
local super
85-
86-
if (classes[superObjName]) then
87-
super = classes[superObjName]
88-
setmetatable(tbl, {__index = super.array})
89-
elseif (interfaces[superObjName]) then
90-
super = interfaces[superObjName]
91-
for i, v in pairs(super) do
92-
tbl[i] = v
77+
function class(className)
78+
local newClasse = {}
79+
local modifiers = {
80+
extends = function(self, superClassName)
81+
return function(subClass)
82+
local superClass = classes[superClassName]
83+
local classCreated = createClass(className, subClass, superClass)
84+
return classCreated
85+
end
86+
end,
87+
88+
implements = function(self, ...)
89+
local interfacesNames = {...}
90+
return function(subClass)
91+
local classeCreated = createClass(className, subClass)
92+
93+
for _, v in pairs(interfacesNames) do
94+
if (not interfaces[v]) then
95+
error('Interface ' .. v .. ' not found', 2)
96+
end
97+
98+
for _, method in pairs(interfaces[v]) do
99+
if (not subClass[method]) then
100+
error('Interface ' .. v .. ' not implemented, method ' .. method .. ' not found', 2)
101+
end
102+
end
103+
end
104+
105+
return classeCreated
93106
end
94107
end
108+
}
95109

96-
return tbl, super
97-
end
98-
end
110+
setmetatable(newClasse, {
111+
__index = function (self, key)
112+
if (modifiers[key]) then
113+
return modifiers[key]
114+
end
99115

100-
function interface(interfaceName)
101-
return function(tbl)
102-
if (not interfaces[interfaceName]) then
103-
interfaces[interfaceName] = {}
104-
end
116+
if (classes[className]) then
117+
return classes[className][key]
118+
end
119+
120+
error('Class ' .. className .. ' not found', 2)
121+
end,
122+
123+
__call = function(self, ...)
124+
if (classes[className]) then
125+
error('Class ' .. className .. ' already exists.', 2)
126+
end
105127

106-
for i, v in pairs(tbl) do
107-
interfaces[interfaceName][v] = v
128+
local newInstance = createClass(className, ...)
129+
return newInstance
108130
end
131+
})
109132

110-
return tbl
111-
end
133+
return newClasse
112134
end
113135

114-
function implements(interfaceName)
115-
return function(tbl)
116-
if (not interfaces[interfaceName]) then error('Interface ' .. interfaceName .. ' not found') end
136+
function new(className)
137+
return function(...)
138+
local classe = classes[className]
139+
if (not classe) then
140+
error('Class ' .. className .. ' not found', 2)
141+
end
117142

118-
for i, v in pairs(interfaces[interfaceName]) do
119-
if (not tbl[v]) then
120-
error('Interface ' .. interfaceName .. ' not implemented, method ' .. v .. ' not found')
121-
end
143+
if (classe.constructor) then
144+
classe:constructor(...)
122145
end
123146

124-
return tbl
147+
return classe
125148
end
126149
end
127150

128151
function instanceOf(instance, className)
129152
local classe = classes[className]
130-
if (not classe) then error('Class ' .. className .. ' not found', 2) end
131-
132-
if (instance._name == className) then
133-
return true
153+
if (not classe) then
154+
error('Class ' .. className .. ' not found', 2)
134155
end
135156

136-
if (instance.super) then
137-
return instanceOf(instance.super, className)
157+
if (instance.__name == className) then
158+
return true
138159
end
139160

140161
return false

0 commit comments

Comments
 (0)