複雜的方法
如果你希望能在外部定義類別的成員,可以參考以下的例子。以 Character.lua 為例子,表格 Character 定義了基本的屬性,__index 則被用來定義預設值。繼承的方式是在新類別使用被繼承類別的 new 方法,使其能使用被繼承類別的元表 (Metatable),並在最外層定義新的屬性與方法。
----------------
-- Character.lua
----------------
-- Define the base object
local Character = { name="Noname", job="Homeless", power=4,
weapon="fist"}
-- Create the metatable; you may want other things like "__newindex"
-- Breaking it out makes it easier
Character.metatable = {}
-- Point the index to ourself
Character.metatable.__index = Character
-- Create the constructor function
-- This lets you pass in table values to override the defaults and make your object unique
function Character:new( newObj )
return setmetatable( newObj, Character.metatable )
end
-- Add a method to the object
function Character:attack()
print(string.format("%s %s use %s with power %d to attack", self.job, self.name, self.weapon, self.power))
end
return Character
----------------
-- Warrior.lua
----------------
local Character = require("Character")
-- Define the base object
local Warrior = Character:new({ job="Warrior", power=100, weapon="sword" })
-- Create the metatable; you may want other things like "__newindex"
-- Breaking it out makes it easier
Warrior.metatable = {}
-- Point the index to ourself
Warrior.metatable.__index = Warrior
-- Create the constructor function
-- This lets you pass in table values to override the defaults and make your object unique
function Warrior:new( newObj )
return setmetatable( newObj, Warrior.metatable )
end
function Warrior:shieldBash()
print(string.format("%s %s use shield bash", self.job, self.name))
end
return Warrior
----------------
--Mage.lua
----------------
local Character = require("Character")
-- Define the base object
Mage = Character:new({ name="Noname", job="Mage", power=4,
weapon="stick"})
-- Create the metatable; you may want other things like "__newindex"
-- Breaking it out makes it easier
Mage.metatable = {}
-- Point the index to ourself
Mage.metatable.__index = Mage
-- Create the constructor function
-- This lets you pass in table values to override the defaults and make your object unique
function Mage:new( newObj )
return setmetatable( newObj, Mage.metatable )
end
-- Add a method to the object
function Mage:attack()
print(string.format("%s %s use %s with power %d to attack", self.job, self.name, self.weapon, self.power))
end
function Mage:fire()
print(string.format("%s %s use fire art", self.job, self.name))
end
function Mage:ice()
print(string.format("%s %s use ice art", self.job, self.name))
end
return Mage
----------------
--Paladin.lua
----------------
local Warrior = require("Warrior")
-- Define the base object
local Paladin = Warrior:new({ job="Paladin", power=200})
-- Create the metatable; you may want other things like "__newindex"
-- Breaking it out makes it easier
Paladin.metatable = {}
-- Point the index to ourself
Paladin.metatable.__index = Paladin
-- Create the constructor function
-- This lets you pass in table values to override the defaults and make your object unique
function Paladin:new( newObj )
return setmetatable( newObj, Paladin.metatable )
end
-- Add a method to the object
function Paladin:heal()
print(string.format("%s %s use heal art", self.job, self.name))
end
return Paladin
----------------
--main.lua
----------------
local Character = require("Character")
local Warrior = require("Warrior")
local Paladin = require("Paladin")
local Mage = require("Mage")
local Kevin = Character:new({name = "kevin"})
local Mary = Mage:new({name = "Mary", power = 5})
local Mark = Mage:new({name = "Mark"})
local Steve = Warrior:new({name = "Hank"})
local Edison = Paladin:new({name = "Edison"})
Kevin:attack()
Mary:attack()
Mary:ice()
Mark:attack()
Mark:fire()
Steve:attack()
Steve:shieldBash()
Edison:attack()
Edison:shieldBash()
Edison:heal()
輸出
兩種方法的輸出都是相同的,如下:
Homeless kevin use fist with power 4 to attack
Mage Mary use stick with power 5 to attack
Mage Mary use ice art
Mage Mark use stick with power 4 to attack
Mage Mark use fire art
Warrior Hank use sword with power 100 to attack
Warrior Hank use shield bash
Warrior Edison use sword with power 200 to attack
Warrior Edison use shield bash
Warrior Edison use heal art