《Lua程序设计(第4版)》面向对象(Object-Oriented)编程

面向对象(Object-Oriented)编程

Lua语言中的一张表就是一个对象,表与对象一样,可以拥有状态。
表与对象一样,拥有一个与其值无关的的标识(self)
两个具有相同值的对象(表)是两个不同的对象,而一个对象可以具有多个不同的值;
最后,表与对象一样,具有与创建者和被创建位置无关的生命周期。
参数self是所有面向对象语言的核心点。大多数面向对象语言都向程序员隐藏了这个机制。Lua语言同样可以使用冒号操作符隐藏该参数。
例:

	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.00)
    Account:withdraw(100.00)`

类(Class)

大多数面向对象语言提供了类的概念,类在对象的创建中扮演了模子的作用。
在这些语言中,每个对象都是某个特定类的实例。
Lua语言中没有类的概念,基于原型的语言中的一些做法来在Lua语言中模拟类。
每个对象可以有一个原型。原型也是一种普通的对象,当对象(类的实例)遇到一个未知操作时会首先在原型中查找。

功能快捷键

大多数面向对象语言提供了类的概念,类在对象的创建中扮演了模子的作用。 在这些语言中,每个对象都是某个特定类的实例。
Lua语言中没有类的概念,基于原型的语言中的一些做法来在Lua语言中模拟类。
每个对象可以有一个原型。原型也是一种普通的对象,当对象(类的实例)遇到一个未知操作时会首先在原型中查找。
在 l u a 中 调 用 方 法 一 定 要 用 冒 号 “ : ” , 不 然 会 a t t e m p t t o i n d e x l o c a l ′ s e l f ′ ( a n i l v a l u e ) \color{#FF0000}{在lua中调用方法一定要用冒号“:”,不然会attempt to index local 'self' (a nil value)} lua:attempttoindexlocalself(anilvalue)

继承(Inheritance)

例:

    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。不过,现在执行new时,它的self参数指向的是SpecialAccount。
    SpecialAccount = Account:new()
    s = SpecialAccount:new{limit = 1000.00}

    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:deposit(100)
    s:withdraw(1800.00)
    print(s.balance)

多重继承(Multiple Inheritance)

Lua语言中实现多重继承,关键在于把一个函数用作__index元方法,当一个表的元表中的__index字段为一个函数时,当Lua不能在原来的表中找到一个键时就会调用这个函数。
例:

	require "Account"
    -- 在表"plist"的列表中查找"k"
    local function search(k, plist)
        for i = 1, #plist do
            -- 尝试第'i'个超类
            local v = plist[i][k]
            if v then return v end
        end
    end

    function createClass( ... )
        local c = {}    --新类
        local parents = {...}  --父类列表

        --在父类列表中查找类缺失的方法
        setmetatable(c, {__index = function ( t, k )
            return search(k, parents)
        end})

    --将'c'作为其实例的元表
    c.__index = c

    --为新类定义一个新的构造函数
    function c:new( o )
        o = o or {}
        setmetatable(o, c)
        return o
    end

    return c --返回新类
    end

    Named = {}
    function Named:getname()
        return self.name
    end

    function Named:setname(n)
        self.name = n
    end

    NamedAccount = createClass(Account, Named)
    acccount = NamedAccount:new{name = "Paul"}

    print(acccount:getname())
	var foo = 'bar';

私有性(Privacy)

Lua语言中标准的对象实现方式没有提供私有性机制,如果读者不想访问一个对象内的内容,那就不要去访问就是了。一种常见的做法是把所有私有名称的最后加上一个下画线,这样就能立刻区分出全局名称了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值