基于分类的继承在LUA中如何起作用



我一直在阅读有关继承的LUA教科书,但我不太了解如何实现它。说我有这两个类:

Hero = {}
function Hero.new(n)
  local self = {name = n, health = 100}
  local dealDamage = function(self)
    return 10
  end
  local takeDamage = function(self, h)
    self.health = self.health - h
  end
  local getHealth = function(self, h)
    self.health = self.health + h
  end
  local getName = function(self)
    return self.name
  end
  local isDead = function(self)
    if self.health <= 0 then
      return true
    end
  return false
  end
   local __tostring = function(self) 
    return "Hero[Name: "..self.name..", health: "..self.health.."]" 
  end
  local mt = {
    __tostring = __tostring
  }
  return setmetatable({
    name = self.name,
    health = self.health,
    dealDamage = dealDamage,
    takeDamage = takeDamage,
    getHealth = getHealth,
    getName = getName,
    isDead = isDead
  }, mt)
end
return Hero

heroClass = require "hero"
Fighter = {}
function Fighter.new(hero)
  local self = {strength = 3}
  local beserk = function(health)
    damage = heath * 0.33
    health = health - (health * 0.25
    return damage
  end
  local __tostring = function(self) 
    return "Fighter[Name: "..name..", health: "..health.."]" 
  end
  local mt = {
    __tostring = __tostring
  }
  return setmetatable({
      strength = self.strength,
    }, mt)
end
return Fighter

我认为我做错了什么是如何使用MetaTables进行班级。使用此类示例或其他几个示例,我可以看到我们的课程大不相同。

您如何正确地设置"继承",其中战斗机类将继承英雄类的功能和数据字段?

在LUA中定义类有许多不同的方法。让我们看一下您拥有的内容,并尝试定义系统应如何工作。

您的Hero类定义一个构造函数,该构造函数返回一个对象,其中所有方法和实例变量直接在该对象上都包含。这是一个非常简单的概念。我唯一要做的更改是从顶部删除self变量,因为您没有真正使用它:

function Hero.new(name)
  local dealDamage = function(self)
    return 10
  end
  local takeDamage = function(self, h)
    self.health = self.health - h
  end
  local getHealth = function(self, h)
    self.health = self.health + h
  end
  local getName = function(self)
    return self.name
  end
  local isDead = function(self)
    return self.health <= 0
  end
  local __tostring = function(self) 
    return "Hero[Name: "..self.name..", health: "..self.health.."]" 
  end
  local mt = {
    __tostring = __tostring
  }
  return setmetatable({
    name = name,
    health = 100,
    dealDamage = dealDamage,
    takeDamage = takeDamage,
    getHealth = getHealth,
    getName = getName,
    isDead = isDead
  }, mt)
end

对于您的Fighter类,我们可以从Hero创建一个基本实例,并使用__index从其继承。(我删除了berserk函数,因为它没有使用。

-- We need the same parameter as Hero.
function Fighter.new(name)
  -- Create a base object by instantiating Hero.
  local hero = heroClass.new(name)
  local __tostring = function(self) 
    return "Fighter[Name: "..self.name..", health: "..self.health.."]" 
  end
  local mt = {
    __tostring = __tostring,
    -- Inherit from the base object.
    __index = hero,
  }
  return setmetatable({
      strength = 3,
  }, mt)
end

该系统的优点是:

  1. 与大多数系统相比,间接性少。您只需查看方法而不是查找班级表。

  2. 继承是灵活的。您可以通过修改构造函数来更改其工作方式。您可以复制方法而不是使用__index,也可以在构造函数中实现多个继承!

我将该系统的缺点作为练习给读者。

最新更新