类和方法示例

lua-users home
wiki

Lua 的类和方法实现

在发现 Lua(有史以来最伟大的脚本语言之一)的最初兴奋过后,我开始尝试使用类和方法。我查看了各种实现,发现 Christian Lindig(lindig |at| cs.uni-sb.de)的实现是最简洁的方法。但是,我注意到,还有改进的空间,可以使它更易于理解。在 Christian Lindig 的代码中,我添加了轻松添加类构造函数的功能,而无需直接处理 obj。

如何使用 INC_Class.lua

以下代码展示了类构造函数和继承功能的示例。请注意,类 cTiger 如何通过

cTiger = setclass("Tiger", cAnimal)

并且请注意,如果您有一个名为“init”的类方法,代码将在您调用 class:new() 时自动执行。

示例代码

require("INC_Class.lua")

--===========================

cAnimal=setclass("Animal")

function cAnimal.methods:init(action, cutename) 
	self.superaction = action
	self.supercutename = cutename
end

--==========================

cTiger=setclass("Tiger", cAnimal)

function cTiger.methods:init(cutename) 
	self:init_super("HUNT (Tiger)", "Zoo Animal (Tiger)")
	self.action = "ROAR FOR ME!!"
	self.cutename = cutename
end

--==========================

Tiger1 = cAnimal:new("HUNT", "Zoo Animal")
Tiger2 = cTiger:new("Mr Grumpy")
Tiger3 = cTiger:new("Mr Hungry")

print("CLASSNAME FOR TIGER1 = ", Tiger1:classname())   
print("CLASSNAME FOR TIGER2 = ", Tiger2:classname()) 
print("CLASSNAME FOR TIGER3 = ", Tiger3:classname()) 
print("===============")
print("SUPER ACTION",Tiger1.superaction)
print("SUPER CUTENAME",Tiger1.supercutename)
print("ACTION        ",Tiger1.action)
print("CUTENAME",Tiger1.cutename)
print("===============")
print("SUPER ACTION",Tiger2.superaction)
print("SUPER CUTENAME",Tiger2.supercutename)
print("ACTION        ",Tiger2.action)
print("CUTENAME",Tiger2.cutename)
print("===============")
print("SUPER ACTION",Tiger3.superaction)
print("SUPER CUTENAME",Tiger3.supercutename)
print("ACTION        ",Tiger3.action)
print("CUTENAME",Tiger3.cutename)

类实现

-----------------------------------------------------
---- SETCLASS CLONES THE BASIC OBJECT CLASS TO CREATE NEW CLASSES
-----------------------------------------------------
-- Supports INHERITANCE 
--
-- Sam Lie, 17 May 2004 
-- Modified Code from Christian Lindig - lindig (at) cs.uni-sb.de
---------------------------------------------------------------

-- EVERYTHING INHERITS FROM THIS BASIC OBJECT CLASS
BaseObject = {
  super   = nil,
  name    = "Object",
  new     =
    function(class)
      local obj  = {class = class}
      local meta = {
        __index = function(self,key) return class.methods[key] end 
      }            
      setmetatable(obj,meta)
      return obj
    end,
  methods = {classname = function(self) return(self.class.name) end},
  data    = {}
}

function setclass(name, super)
  if (super == nil) then
    super = BaseObject
  end

  local class = {
    super = super; 
    name  = name; 
    new   =
      function(self, ...) 
        local obj = super.new(self, "___CREATE_ONLY___");
          -- check if calling function init
          -- pass arguments into init function
        if (super.methods.init) then
          obj.init_super = super.methods.init
        end

	if (self.methods.init) then
            if (tostring(arg[1]) ~= "___CREATE_ONLY___") then
              obj.init = self.methods.init
              if obj.init then
                obj:init(unpack(arg))
              end
            end
	end

        return obj
      end,  
    methods = {}
  }
    
  -- if class slot unavailable, check super class
  -- if applied to argument, pass it to the class method new        
  setmetatable(class, {
    __index = function(self,key) return self.super[key] end,
    __call  = function(self,...) return self.new(self,unpack(arg)) end 
  })

  -- if instance method unavailable, check method slot in super class    
  setmetatable(class.methods, {
    __index = function(self,key) return class.super.methods[key] end
  })
  return class
end    

[email protected],2004 年 5 月 17 日

另请参阅


最近更改 · 偏好设置
编辑 · 历史记录
最后编辑于 2009 年 12 月 26 日凌晨 2:21 GMT (差异)