Lua 与C/C++ 交互系列:Lua面向对象编程翻译


本文翻译来自:Programming with Multiple Paradigms in Lua


原文如下:

Object-Oriented Programming
Lua has only one data-structure mechanism, the table. Tables are first-class,
dynamically created associative arrays.
Tables plus first-class functions already give Lua partial support for objects.
An object may be represented by a table: instance variables are regular table
fields and methods are table fields containing functions. 
In particular, tables have identity.
That is, a table is different from other tables even if they have the
same contents, but it is equal to itself even if it changes its contents over time.
One missing ingredient in the mix of tables with first-class functions is how
to connect method calls with their respective objects. If obj is a table with a method foo and we call obj.foo(), foo will have no reference to obj.
We could solve this problem by making foo a closure with an internal reference to obj,
but that is expensive, as each object would need its own closure for each of its
methods.
A better mechanism would be to pass the receiver as a hidden argument to
the method, as most object-oriented languages do.
Lua supports this mechanism with a dedicated syntactic sugar, the colon operator: the syntax orb:foo() is
sugar for orb.foo(orb), so that the receiver is passed as an extra argument to the method. 
There is a similar sugar for method definitions. 
The syntax
function obj:foo (...) ... end
is sugar for
obj.foo = function (self, ...) ... end
That is, the colon adds an extra parameter to the function, with the fixed name self.
The function body then may access instance variables as regular fields of table self.


To implement classes and inheritance, Lua uses delegation.
Delegation in Lua is very simple and is not directly connected with object-oriented programming;
it is a concept that applies to any table.Any table may have a designated “parent” table.
Let us see how this works. Let us assume an object obj and a call obj:foo().
This call actually means obj.foo(obj), so Lua first looks for the key foo in table obj.
If obj has such field, the call proceeds normally.
Otherwise, Lua looks for that key in the parent of obj. Once it found a value for that key, Lua calls the value (which should be a function) with the original object obj as the first argument, so that obj becomes the value of the parameter self inside the method’s body.
With delegation, a class is simply an object that keeps methods to be used by its instances. 
A class object typically has constructor methods too, which are used by the class itself. 
A constructor method creates a new table and makes it delegates its accesses to the class, so that any class method works over the new object.
If the parent object has a parent, the query for a method may trigger another query in the parent’s parent, and so on. 
Therefore, we may use the same delegation mechanism to implement inheritance. 
In this setting, an object representing a (sub)class delegates accesses to unknown methods to another object  representing its superclass.
For more advanced uses, a program may set a function as the parent of a table. 
In that case, whenever Lua cannot find a key in the table it calls the parent function to do the query.
 This mechanism allows several useful patterns, such as multiple inheritance and inter-language inheritance (where a Lua object may delegate to a C object, for instance).

翻译如下:

Table是Lua语言仅仅有一个数据结构机制。Table作为first-class 动态创建的关联数组.
Table和first-class函数提供了部分支持对象的机制。
一个Table就代表了一个对象Object:成员变量就是Table的字段,方法就是Table中包含的first-class方法。
特别地,Table具有唯一性。尽管两个Table有一样的内容,但是Table仅仅和自己相等。
使用Table和first-class函数的缺失部分是如何表示对象的成员函数。
如果obj是一个带有foo函数的table,当调用obj.foo()函数时,foo没有引用obj.
Lua提供一个更好的机制来实现像面向对象语言那样来隐藏函数的参数到调用者那里。
Lua提供一个语法糖机制,使用冒号符号来隐藏函数的参数。 
为了在Lua语言中实现类和继承,Lua使用delegation来实现。
在Lua里面的delegation 是非常简单,并且不直接管理面向对象语言。
delegation概念被应用到任何Table。Table可以拥有一个设计好的"父类"Table.
Whenever Lua fails to find a field in a table, it tries to find that field in the parent table. 
In other words, Lua delegates field accesses instead of method calls.
当Lua在Table中查询到字段失败时,Lua就尝试在父类Table中查询字段。
换言之,Lua delegation field 用来代替函数调用。
通过delegation,一个类型Class是一个简单的拥有方法的对象。
一个类对象同时拥有构造方法。
所以,在Lua语言中使用代理机制来实现类的继承。
代理机制允许多种有用的设计模式,例如多重继承和过渡语言继承(使用Lua对象可以代理在C语言对象)


注: 文中提到的delegation 是通过metatable 来实现。在上一篇文章中metatable和__index来实现的面向对象调用。


你可能感兴趣的:(Lua,与C/C++,交互系列)