Multiple Inheritance

How can multiple inheritance be achieved in Codea?
If I wanted class C to inherit both class A and B, what should I do?

See this current thread

http://codea.io/talk/discussion/6446/draggable-objects-and-design-patterns

i use this (not sure how othodox it is…)

-- this is to grab fields from another class
function mixin(target,source,field)
    local fields = field
    if type(fields) == "string" then fields = {field} end
    for i,key in ipairs(fields) do
        if type(key) ~= "string" then error("mixin must have only string(s) for field") end
        local v = source[key] 
        if v == nil then error("field '"..key.."' is nil") end
        target[key] = v
    end
end

so it could be:

C = class(A)
mixin(C, B, B)

however it will work only for functions directly declared in B, not for the functions that B may inherit from class D if B = class(D). Because D keys are not in B, they are found for b= B() instances, and only after you’ve called them for the first time.

Thanks @Ignatz and @Jmv38!

@Ignatz I was wondering if there is a component based example where Class C would be defined as a descendant of both classes A and B, without classes A or B knowing anything about each other. Is it possible to do something like:

C = class(A, B)

Then class C can be initialized with the member variables inherited from both its parents, A and B?

@the_dude- you can kludge it as below, by having a parent class A, and defining the sub classes as tables instead of classes. Then you can pass the sub classes to A and it can copy their functions into itself.

But I think a better component approach is shown in the thread I linked above.

function setup()
    d=A("test case",B)
    d:a()
    d:b()
    print("B variable is "..d.tag)
    
end

A=class()
function A:init(name,c)
    self.name=name
    if c then 
        for key,val in pairs(c) do
            self[key]=val
        end
    end    
end
function A:a()
    print("A prints "..self.name)
end

B={}
function B:b() print("B prints "..self.name) end
B.tag="BB"


Thanks @Ignatz. Much appreciated.

What about an edit to Codea’s classes?

-- Class.lua
-- Compatible with Lua 5.1 (not 5.0).

function class(...)
    local arg = {...}
    local c = {}    -- a new class instance
    c._bases = {}
    for id, base in ipairs(arg) do
        if type(base) == 'table' then
            -- our new class is a shallow copy of the base class!
            for i,v in pairs(base) do
                c[i] = v
            end
            c._bases[#c._bases + 1] = base
            c._base = base
        end
    end

    -- the class will be the metatable for all its objects,
    -- and they will look up their methods in it.
    c.__index = c

    -- expose a constructor which can be called by <classname>(<args>)
    local mt = {}
    mt.__call = function(class_tbl, ...)
        local obj = {}
        setmetatable(obj,c)
        if class_tbl.init then
            class_tbl.init(obj,...)
        else 
            -- make sure that any stuff from the base class is initialized!
            if base and base.init then
                base.init(obj, ...)
            end
        end
        
        return obj
    end

    c.is_a = function(self, klass)
        local m = getmetatable(self)
        while m do 
            if m == klass then return true end
            m = m._base
        end
        return false
    end

    setmetatable(c, mt)
    return c
end

That should let you call A = class(B, C) and have A inherit functions from both B and C.

There’s a reason why C++ and Java don’t have multiple inheritance, why would you need it? Inheritance can bring an awful lot of baggage - especially if you have a complex hierarchy. Modern thinking tends to favour a component based approach instead - KISS!