• 面向对象程序设计关于Lua的初识


    Lua 中的表不仅在某种意义上是一种对象。像对象一样,表也有状态(成员变量);也有与对象的值独立的本性,特别是拥有两个不同值的对象(table)代表两个不同的对象;一个对象在不同的时候也可以有不同的值,但他始终是一个对象;与对象类似,表的生命周期与其由什么创建、在哪创建没有关系。对象有他们的成员函数,表也有:

    我们可以把它看成一张含有两个方法, 一个数值的表, 同时也可以把它当作是 一个银行账户的类。

    ------------------Lua面向对象程序设计
    --我们可以把它看成一张含有两个方法, 一个数值的表, 同时也可以把它当作是 一个银行账户的类
    
    Account = { blance = 0 } --  余额为0的账户
    
    function Account.withdraw(v) --取款
       Account.blance = Account.blance - v
    end
    
    function Account.deposit(v) --存款
       Account.blance = Account.blance + v
    end
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    这个定义创建了一个新的函数,并且保存在 Account 对象的 withdraw 域内,下面我们可以这样调用:

    Account.withdraw(100)
    
    • 1

    这种函数就是我们所谓的方法,然而,在一个函数内部使用全局变量名 Account 是一个不好的习惯。首先,这个函数只能在这个特殊的对象(译者:指 Account)中使用;第二,即使对这个特殊的对象而言,这个函数也只有在对象被存储在特殊的变量(译者:指 Account)中才可以使用。如果我们改变了这个对象的名字,函数 withdraw 将不能工
    作:

    a = Account
    Account = nil
    a.withdraw(100)   --error
    
    • 1
    • 2
    • 3

    这种行为违背了前面的对象应该有独立的生命周期的原则。

    一个灵活的方法是:定义方法的时候带上一个额外的参数,来表示方法作用的对象。这个参数经常为 self 或者 this

    Account = { blance = 0 } --  余额为0的账户
    
    function Account.withdraw(self,v) --取款
       self.blance = self.blance - v
    end
    
    function Account.deposit(self,v) --存款
       self.blance =self.blance + v
    end
    
    Account.withdraw(Account,100)
    print(Account.blance)  --  -100
    
    a=Account         --这样我们就可以用一张新表来作为Account的对象了:
    Account=nil
    a.withdraw(a,100)
    print(a.blance)   --  -200
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    输出结果:

    -100
    -200
    
    • 1
    • 2

    self 参数的使用是很多面向对象语言的要点。大多数语言将这种机制隐藏起来,这样程序员不必声明这个参数(虽然仍然可以在方法内使用这个参数)。 Lua 也提供了通过使用冒号操作符来隐藏这个参数的声明。我们可以重写上面的代码:

    Account = { blance = 0 }
    
    function Account:withdraw(v)
       self.blance=self.blance-v
    end
    
    function Account:deposit(v)
       self.blance=self.blance+v
    end
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    调用方法如下:

    Account:withdraw(100)
    
    A=Account
    A:withdraw(100)
    
    Account.deposit(Account,200)
    print(Account.blance)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    输出结果:

    0
    
    • 1

    冒号的效果相当于在函数定义和函数调用的时候,增加一个额外的隐藏参数。这种方式只是提供了一种方便的语法,实际上并没有什么新的内容。我们可以使用 dot 语法定义函数而用冒号语法调用函数,反之亦然,只要我们正确的处理好额外的参数

    Account = {
       balance = 0,
       withdraw = function(self, v)
          self.balance = self.balance - v
       end
    }
    function Account:deposit(v)
       self.balance = self.balance + v
    end
    
    Account.deposit(Account, 200)
    Account:withdraw(100)
    
    print(Account.balance)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    输出结果:

    100
    
    • 1

    现在我们的对象拥有一个标示符,一个状态和操作这个状态的方法。但他们依然缺少一个 class 系统,继承和隐藏。先解决第一个问题:我们如何才能创建拥有相似行为的多个对象呢?明确地说,我们怎样才能创建多个 accounts(译者:针对上面的对象Account 而言)

  • 相关阅读:
    [框架设计之道(二)]设备、任务设置及业务流程
    微信小程序ibeacon搜索功能制作
    使用SpaceDesk实现iPad成为电脑拓展屏(保姆级教程)
    批量替换WordPress文章内图片链接
    规则引擎Drools在贷后催收业务中的应用
    向上管理读书笔记
    优化算法——全局灵敏度分析算法(PAWN )(Matlab代码实现)
    A tour of gRPC:07 - gRPC bidirectional straming 双向流
    正交试验测试用例设计及工具推荐
    代码随想录day43|1049. 最后一块石头的重量 II494. 目标和474. 一和零
  • 原文地址:https://blog.csdn.net/qq_44918090/article/details/126513632