a0405u
a0405u

Reputation: 45

Lua inheritance and methods

How to inherit a new class player from class actor and make method actor:new(x, y, s) called in method player:new(x, y, s) with the same parameters. I need to make player:new the same but with additional parameters so the player can have more properties than actor.

Is there a way to do this not only in new method, but in other methods, like player:move(x, y) will call actor:move(x, y) or self:move(x, y) but with additional code?

I use this pattern to make classes in modules:

local actor = {}

function actor:new(x, y, s)

    self.__index = self

    return setmetatable({
        posx = x,
        posy = y,

        sprite = s
    }, self)
end

-- methods

return actor

Upvotes: 2

Views: 682

Answers (1)

Piglet
Piglet

Reputation: 28994

A good way to do this is to have a separate function that initializes your instance. Then you can simply call the base classes initialization within the inherited class.

Like in this example: http://lua-users.org/wiki/ObjectOrientationTutorial

function CreateClass(...)
  -- "cls" is the new class
  local cls, bases = {}, {...}
  -- copy base class contents into the new class
  for i, base in ipairs(bases) do
    for k, v in pairs(base) do
      cls[k] = v
    end
  end
  -- set the class's __index, and start filling an "is_a" table that contains this class and all of its bases
  -- so you can do an "instance of" check using my_instance.is_a[MyClass]
  cls.__index, cls.is_a = cls, {[cls] = true}
  for i, base in ipairs(bases) do
    for c in pairs(base.is_a) do
      cls.is_a[c] = true
    end
    cls.is_a[base] = true
  end
  -- the class's __call metamethod
  setmetatable(cls, {__call = function (c, ...)
    local instance = setmetatable({}, c)
    -- run the init method if it's there
    local init = instance._init
    if init then init(instance, ...) end
    return instance
  end})
  -- return the new class table, that's ready to fill with methods
  return cls
end

You would simply do:

actor = CreateClass()
function actor:_init(x,y,s)
  self.posx = x
  self.posy = y
  self.sprite = s
end

player = CreateClass(actor)
function player:_init(x,y,s,name)
  actor.init(self, x,y,s)
  self.name = name or "John Doe"
end

Upvotes: 2

Related Questions