Lua类继承问题 [英] Lua class inheritance problem

查看:169
本文介绍了Lua类继承问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个类在Lua。一个继承另一个。

I have two classes in Lua. One inherits another.

test1 = {test1Data = 123, id= {0,3}}
function test1:hello()
    print 'HELLO!'
end
function test1:new (inp)
    inp = inp or {}
    setmetatable(inp, self)
    self.__index = self
    return inp
end
test2 = {}
function test2:bye ()
    print ('BYE!', self.id)
end
function test2:new_inst_test (baseClass, inp)
    inp = inp or {}
    setmetatable(inp, self)
    self.__index = self
    if baseClass then
        setmetatable( inp, { __index = baseClass } )
    end
    return inp
end

a = test1:new({passData='abc1'})
b = test1:new({passData='ghyrty'})

c = test2:new_inst_test(a,{temp = '123343321135'})
d = test2:new_inst_test(b, {temp = '1'})



print (c.temp, c.test1Data, c.passData)
print (d.temp, d.test1Data, d.passData)
c:bye()
c:hello()

我想test2不仅继承test1,而且保存自己的方法('bye')。
是可能吗?
谢谢!

I want test2 not just inherit test1, but save own methods ('bye'). Is it possible? Thanks!

推荐答案

你应该设置一个metatable类__index = baseclass类metatable我想。但是这将改变test2类中所有对象的metatable。这样做,你将使用类本身的方法,当方法不存在于当前类中时,只使用父类中的方法,或者它是可元的。

you should set a metatable with __index=baseclass on the class metatable I think. But that will change the metatable for all objects in the test2 class. Doing it this way, you will use the methods from the class itself, and only use methods from the parent when the method does not exists in the current class, or it's metatable.

所以它应该像

if baseClass then
    setmetatable( self, { __index = baseClass } )
end

另一方面,你只想指定一个新的基类实例,而不是在创建新类时指定它。

On the other hand it's kind of weird that you only specify the baseclass when making a new instance, instead of specifying it when creating the new class. So I'd rethink how you inherit between classes instead of between instances and classes.

这是一个小巫师主题的例子:

As a small wizardry themed example:

--oop.lua Example of OOP and inheritance in Lua
Person={
    age=0,
    className='Person'
}
-- needed if needed add comparisons, operations, ...
mtPerson={}
mtPerson.__index={
    getClassName=function(self)
        return self.className
    end,
    new=function(self,t)    
        return setmetatable(t or {},{__index=self})
    end,
    inherit=function (self,t,methods)
        -- This is the heart of the inheritance: It says:
        -- Look it up in the methods table, and if it's not there, look it up in the parrent class (her called self)
        -- You pass this function the parent class (with :), a table of attributes and a table of methods.
        local mtnew={__index=setmetatable(methods,{__index=self})}
        return setmetatable(t or {},mtnew)
    end,
    introduce=function(self)
        print(("Hi! I'm %s, I'm a %s and I'm %d years old"):format(self.instanceName,self.className,self.age))
    end
    }

setmetatable(Person,mtPerson)

-- Wizard inherits from the class Person, and adds some default values and methods
Wizard=Person:inherit({
    className="Wizard",
    knownSpells={},
    },
    {
    listSpells=function(self)
        print("known spells:",self)
        if #self.knownSpells==0 then
            print'none'
        else
            for k,v in ipairs(self.knownSpells) do
                print(k,v)
            end
        end
    end
    }
)

i1=Person:new{
    inventory={'wallet'},
    instanceName="John",
}

i2=Wizard:new{ -- inherited method "new"
    inventory={'wallet','wand','cloak of invisibility'},
    instanceName="Harry",
    age=20,
    knownSpells={'Avada kavedra', 'Sesame open'}
}

i1:introduce() -- inherited method "introduce" notice that qge is the default value of 0
i2:introduce() -- 

i2:listSpells() -- method only in class 2
i1.age=26
i1:introduce()    -- changed age of instance
print(Person.age)    -- didn't change class defaults
print(Wizard.age)
i1:listSpells() -- Error.

在写这篇文章的时候,我得出结论,Lua中的OOP同时非常简单,非常复杂。你只需要在编写代码之前真正考虑事情,然后坚持计划。因此,在这里,我选择将属性放在类和实例表本身中,并将所有方法放在各自的元表中。我这样做,因为现在很容易迭代通过所有的属性,没有遇到的方法,但任何选择,工作是有效的。你只需要选择一个。

While writing this, I came tho the conclusion that OOP in Lua is at the same time very simple, and very complicated. You simply have to really think things through before writing code, and stick with the plan afterwards. As such, here I chose to put attributes in the class and instance tables themselves, and put all methods in their respective metatables. I did this because now it's easy to iterate through all attributes, without encountering methods, but any choice that works is valid. You just have to pick one.

这篇关于Lua类继承问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆