inheritance - 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
我认为我做错的是如何使用元表构建类。使用这样的示例或其他几个SO问题,我可以看到我们的课程非常不同。
如何正确设置 Fighter 类继承 Hero 类的函数和数据字段的继承?
解决方案
在 Lua 中有许多不同的定义类的方法。与其选择一些 OOP 系统作为“正确”的方式,不如让我们看看您拥有什么并尝试定义您的系统应该如何工作。
您的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
该系统的优点是:
与大多数系统相比,间接性更少。您可以只查看对象的方法,而不是查找类表。
继承是灵活的。您可以通过修改构造函数来更改它的工作方式。您可以复制方法而不是 using
__index
,或者您可以在构造函数中实现多重继承!
我把这个系统的缺点留给读者作为练习。
推荐阅读
- flutter - Flutter - 如何更改 LicensePage 的背景颜色?
- node.js - POST 对象也包含数据库中的数组(反应,nodejs)
- java - 我怎样才能得到简单的 yyyy-MM-dd 这个日期?
- python - 无法在 pdf 的所有面上留出 2.5 厘米的边距
- sql - SQL - 如何在按周和月分组时消除重复的周
- spring - Spring HATEOAS 递归表示模型处理器?
- python - 如何从 URL 获取参数到 Authentification 函数?(Python,烧瓶)
- android - Firebase 身份验证和实时数据库链接
- apache-spark - 是否可以使用 spark 2.4 使用 Hadoop 3.x 和 Hive 3.x?
- javascript - 使用javascript / jquery在网页中查找文本的y位置?