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 に答える