Saltar para o conteúdo

Módulo:Herança

Fonte: Wikiversidade

Este módulo contem uma classe básica juntamente com uma declaração de extensão para herdar de classes existentes. Assim, destina-se a outros scripts Lua e não para ser invocado por páginas wiki.

Por favor, note que a herança funciona apenas com a classe básica introduzida e suas subclasses.

Classe básica com um construtor e verificação de tipo (classe). Com a declaração de extensão abaixo, você pode herdar desta classe e suas subclasses.

Você pode criar uma instância desta classe através de:

local instance = Class();

Embora isso seja possível, considere a classe básica como abstrata e instancie apenas as classes herdadas.

Vazia. Construtor de classe que é chamado de instanciação por padrão. Substitua este método para implementar um construtor personalizado. Uma vez que está vazio, não há motivo para chamar esse construtor básico, a menos que você o implemente.

Checa se esse objeto é uma instância de uma classe específica.

Parâmetros:

  • [Class] aClass: classe que se espera que o objeto seja.

Retorno:
Retorna verdade se o objeto foi uma instância de uma classe específica ou derivada de alguma classe. Do contrário, retorna falso.

Adquire a super classe de onde essa classe é derivada.

Retorno:
Retorna super classe se a classe foi derivada de qualquer classe. Do contrário, retorna nulo ("nil").

A declaração de extensão permite herdar de uma classe. Ele cria uma classe básica que amplia a classe especificada. Por favor, note que a herança apenas funciona com a classe básica introduzida e suas subclasses.

Exemplo:

Uso de declarações:

   local i = require("inheritance");
   local Person = i.extend(i.Class);
   --
   function Person:init(name)
       self.name = name;
   end
   --
   function Person:getName()
       return self.name;
   end

Uso de classe:

   local user = Person("Testy");
   return user:getName();

Parâmetros:

  • [Class] baseClass: classe a ser estendida - precisa ser classe ou derivada de classe.

Retorna:
Retorna uma classe básica que amplia a classe especificada. A nova classe herda todos os métodos e campos da classe base.


local i = {}

local Class = {}
Class.__index = Class;

setmetatable(Class, {
  __call = function (cls, ...)
    local self = setmetatable({}, cls);
    self:init(...);
    return self;
  end,
});

function Class:init()
end

function Class:isa(aClass)
  local crrClass = self;
  while nil ~= crrClass do
    if crrClass == aClass then
      return true;
    end
    crrClass = crrClass:super();
  end
  return false
end

function Class:super()
  return nil;
end

i.Class = Class;

---

function i.extend(baseClass)
  -- limit inheritance to module class tree
  assert(baseClass ~= nil
    and baseClass["isa"] ~= nil
    and baseClass:isa(Class));

  local thisClass = {}
  thisClass.__index = thisClass;
  
  setmetatable(thisClass, {
    __index = baseClass,
    __call = function (cls, ...)
      local self = setmetatable({}, cls)
      self:init(...);
      return self;
    end,
  });
  
  function thisClass:super()
    return baseClass;
  end
  
  return thisClass;
end

return i;