继承(Inheritance)

简介: 继承(Inheritance)

由于类也是对象,因此他们也可以从其他类获得方法。这种行为使得 继承 (即常见的面向对象的定义)可以很容易地在 Lua 语言中实现。


假如有一个类似于 Account基类,如下所示:

Account = { balance = 0 }
function Account:new(o)
  o = o or {}
  self.__index = self
  setmetatable(o,self)
  return o
end
function Account:deposit(v)
  self.balance = self.balance + v
end
function Account:withdraw(v)
  if v > self.balance then error"insufficient funds" end
  self.balance = self.balance -v
end


若想从这个类派生一个子类 SpecialAccount 以允许客户透支,那么可以先创建一个从基类继承了所有操作的空类:

SpecialAccount = Account:new()


直到现在, SpecialAccount 还只是 Account 的一个实例。下面让我们来见证奇迹:

s = SpecialAccount:new{limit=100.00}


SpecialAccount 就像继承其他方法一样从 Account 继承了 new 。不过,现在执行 new 时,它的 self 参数指向的是 SpecialAccount 。因此, s 的元表会是 SpecialAccount ,其中字段 __index 的值也是 SpecialAccount 。因此, s继承自SpecialAccount ,而 SpecialAccount 又继承自 Account 。之后,执行 s:deposit(100.00) 时, Lua 语言在 s 中找不到 deposit 字段,就会查找 SpecialAccount ,仍然找不到 deposit 字段,就查找 Account 并最终会在 Account 中找到 deposit 的最初实现。


SpecialAccount 之所以特殊是因为我们可以重新定义从基类继承的任意方法,只需要编写一个新方法即可:

function SpecialAccount:withdraw(v)
  if v - self.balance >= self:getLimit() then
    error:"insufficient funds"
  end
  self.balance = self.balance -v
end
function SpecialAccount:getLimit()
  return self.limit or 0
end


现在,当调用 s:withdraw(200.00) 时,因为 Lua 语言会在 SpecialAccount 中先找到新的 withdraw 方法,所以不会再从 Account 中查找。由于 s.limit100.00 (我们创建s时设置了这个值),所以程序会执行取款并使得 s 变成负的余额。


Lua 语言中的对象有一个有趣的特性,就是无须为了指定一种新行为而创建一个新类。如果只有单个对象需要某种特殊的行为,那么我们可以直接在该对象中实现这个行为。例如,假设账户 s 表示一个特殊的客户,这个客户的透支额度总是其余额的 10% ,那么可以只修改这个账户:

function s:getLimit()
  return self.balance * 0.10
end


在这段代码后,调用 s:withdraw(200.00) 还是会执行 SpecialAccountwithdraw 方法,但当 withdraw 调用 self:getLimit 时,调用的是上述的定义。

目录
相关文章
|
5月前
|
Java 编译器 程序员
关于继承是怎么样的?那当然是很好理解之
关于继承是怎么样的?那当然是很好理解之
28 1
|
5月前
|
C++
8. C++继承
8. C++继承
48 0
|
6天前
|
Java 编译器
继承详解13
继承详解13
16 0
|
2月前
|
安全 Java 编译器
|
5月前
|
编译器
|
5月前
|
编译器 C++
【继承】初步了解C++继承
【继承】初步了解C++继承
|
5月前
|
存储 编译器 C++
C++中的继承
C++中的继承
28 0
|
5月前
|
C++
c++继承
c++继承
20 0
继承的相关知识总结
继承的相关知识总结
48 0
|
5月前
|
存储 设计模式 Java
C++【继承】
C++【继承】
64 0