Skip to content

Instantly share code, notes, and snippets.

@forflo
Last active August 29, 2015 14:20
Show Gist options
  • Save forflo/9ba502493c2c5772c7d0 to your computer and use it in GitHub Desktop.
Save forflo/9ba502493c2c5772c7d0 to your computer and use it in GitHub Desktop.
Inheritance, Encapsulation, and Classes in LUA
--[[
Multi level inheritance implemented using only
tables and meta tables in lua
The implementation follows the very simple scheme:
class_inheritancelevel_n = {
new = function(self, inh)
new = {}
for k, v in pairs(self) do
new[k] = v
end
-- default values for fields
new.vals = {}
-- inheritance
new.meta = {__index = new }
if inh then setmetatable(inh, new.meta)
if inh then return inh else return new end
end
-- [some fields and some methods]
-- this is mandatory for all derivations
meta = nil
}
---------------------------------------
Alterations with respect to oop_02.lua:
privated fields!!!
]]
matrix = {
new = function(self)
-- private fields
meta = {}
vals = {}
return function(inh)
new = {}
for k, v in pairs(self) do
new[k] = v
end
-- defaults for the fields
meta = { __index = new }
-- operations
new.add = function(self, this_matrix)
local svals = #vals
for k=1, #this_matrix do
vals[k + svals] = this_matrix[k]
end
end
new.get_length = function(self)
return #vals
end
new.get_vals = function(self)
local copy = {}
for k, v in pairs(vals) do
copy[k] = v
end
return copy
end
new.tostring = function(self)
local res = ""
for k, v in pairs(vals) do
res = res .. v .." "
end
return res
end
-- inheritance
if inh then
setmetatable(inh, meta)
end
-- new table instance
if inh then
return inh
else
return new
end
end
end
-- public fields
-- ....
}
matrix_i1 = {
new = function(self)
-- private fields
meta = {}
counter = 0
return function(inh)
new = {}
for k, v in pairs(self) do
new[k] = v
end
new.i2_counter = 43
-- methods
new.get_vals_as_string = function(self)
local res = ""
for k, v in pairs(self.get_vals()) do
res = res .. v
end
return res
end
new.get_counter = function(self)
return counter
end
new.set_counter = function(self, val)
counter = val
end
-- inheritance
meta = { __index = new }
if inh then
setmetatable(inh, meta)
end
if inh then
return inh
else
return new
end
end
end,
-- public fields
i2_counter = nil
}
matrix_i2 = {
new = function(self)
-- private fields and methods
meta = {}
return function(inh)
new = {}
for k, v in pairs(self) do
new[k] = v
end
-- inheritance
meta = { __index = new }
if inh then
setmetatable(inh, meta)
end
if inh then
return inh
else
return new
end
end
end,
-- public fields and methods without access to private data structs
moo = function(self) print(self) end
}
m = matrix:new()()
m:add{1,2,3}
m:add{"Foo", "bar"}
print("m: (first) " .. m:tostring())
m = matrix:new()(matrix_i1:new()())
m:add{1,2,3}
m:add{"Foo", "bar"}
-- set_counter is private for matrix_i1
m:set_counter(34543234)
print("mi1: counter:" .. m:get_counter())
print("mi1: (second) " .. m:tostring())
print("mi1: (third) " .. m:get_vals_as_string())
-- determins the following inheritance relationships
-- matrix <- matrix_i1 <- matrix_i2
m = matrix:new()(matrix_i1:new()(matrix_i2:new()()))
m:add{1,2,3}
m:add{"Foo", "bar"}
print("mi2: (fourth)" .. m:tostring())
m:moo()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment