4

我正在努力理解元表是如何工作的,以及为什么在 Lua 中需要它们来创建类和继承。我为 Lua 找到的每个 OOP 示例都与上一个有所不同,但它们总是使用元表,特别是针对__index属性。以下是我如何实现一些简单的继承:

Animal = {}

function Animal.New()
  local self = {}
  self.sName = "Generic Animal"

  self.GetName = function(self)
    return self.sName
  end

  self.Speak = function(self)
    -- Do nothing, abstract function
  end

  return self
end

Dog = {}

function Dog.New()
  local self = Animal.New()
  self.sName = "Dog"

  self.Speak = function(self)
    print("Bark!")
  end

  return self
end

Labrador = {}

function Labrador.New()
  local self = Dog.New()
  self.sName = "Labrador"
  return self
end

Chihuahua = {}

function Chihuahua.New()
  local self = Dog.New()
  self.sName = "Chihuahua"

  self.Speak = function(self)
    print("Yap yap!")
  end

  return self
end

-- Test --

l = Labrador.New()
print(l:GetName())
l:Speak()

c = Chihuahua.New()
print(c:GetName())
c:Speak()

d = Dog.New()
print(d:GetName())
d:Speak()

a = Animal.New()
print(a:GetName())
a:Speak()

输出:

Labrador
Bark!
Chihuahua
Yap yap!
Dog
Bark!
Generic Animal

据我所知,这很好用。使用元表将如何改进我的设计?

4

1 回答 1

1

没有人说OOP需要元表。它们是有用的,不是必需的。

元表允许您隐藏数据。我可以很容易地破坏你所有仔细的编码:

local dog = Chihuahua.New()
dog.sName = nil --Oops.
dog.GetName = nil --Oops.

它还允许其他可疑的构造,例如在对象中存储其他数据:dog.newVar = foo.

OOP 不仅仅是继承。好的 OOP 还应该包含封装,以防止意外误用对象的完整性。__index元表允许您通过对主表使用空表并过滤所有设置和通过元方法来执行此__newindex操作。这样,只有对象才能在实际表中存储数据。除非您提供显式访问权限,否则只有对象可以检索它。

于 2013-02-12T18:34:40.800 回答