zoukankan      html  css  js  c++  java
  • [Lua]面向对象

    这里主要说一下Lua在面向对象的使用中需要注意的地方。

    一.self

    self指的是调用者自身,例如:

    local a = Shape:New(nil, 10),即local a = Shape.New(self, nil, 10),self指的是Shape;

    a:PrintArea(),即a.PrintArea(self),self指的是a。

     1 Shape = {area = 0}
     2 
     3 function Shape:New(o, side)
     4     o = o or {}
     5     setmetatable(o, self)
     6     self.__index = self
     7     side = side or 0
     8     self.area = side * side
     9     return o
    10 end
    11 
    12 function Shape:PrintArea()
    13     print("面积为 ", self.area)
    14 end
    15 
    16 print(Shape.area)
    17 
    18 local a = Shape:New(nil, 10)
    19 a:PrintArea()
    20 print(Shape.area)
    21 
    22 local b = Shape:New(nil, 20)
    23 b:PrintArea()
    24 print(Shape.area)
    25 
    26 a:PrintArea()
    27 print(Shape.area)

    输出分析:

    第二句,在Shape:New(nil, 10)时,Shape.area被赋值为100,在a:PrintArea()时,本来要打印的是a.area,但该键值为空,实际打印的是Shape.area。

    第六句,在Shape:New(nil, 20)时,Shape.area被赋值为400。

    那么,可以将上面的self.area = side * side改一下,改为o.area = side * side,输出如下。可以看到,此时New出来的实例都有各自的area值,不影响Shape表,此时才是符合面向对象设计的。

    二.元表的__index元方法

    __index元方法是用来查找值的,因此可以认为是“可读不可写”的。当查找到表中的某键的值为nil时,就会访问元表的__index元方法。

    如下输出所示,可以发现:

    1.像a.xxx这种,都是直接对a表进行赋值,不影响Shape表;而a.testTb[2]这种非直接赋值,会影响Shape表

     1 Shape = {area = 0, test = 123, testTb = {"q","w"}}
     2 
     3 function Shape:New(o, side)
     4     o = o or {}
     5     setmetatable(o, self)
     6     self.__index = self
     7     side = side or 0
     8     --self.area = side * side
     9     o.area = side * side
    10     return o
    11 end
    12 
    13 function Shape:PrintArea()
    14     print("面积为 ", self.area)
    15 end
    16 
    17 local a = Shape:New(nil, 10)
    18 print(a.test)
    19 print(a.test2)
    20 print(Shape.test)
    21 
    22 print("------------------------")
    23 a.test = 456
    24 print(a.test)
    25 print(Shape.test)
    26 
    27 print("------------------------")
    28 Shape.test = 789
    29 print(a.test)
    30 print(Shape.test)
    31 
    32 print("------------------------1")
    33 print(a.testTb[2])
    34 a.testTb[2] = "z"
    35 
    36 print("------------------------2")
    37 a.testTb = nil
    38 for i=1,#a.testTb do
    39     print(a.testTb[i])
    40 end
    41 print("------------------------3")
    42 for i=1,#Shape.testTb do
    43     print(Shape.testTb[i])
    44 end
    45 
    46 print("------------------------4")
    47 a.testTb = {}
    48 for i=1,#a.testTb do
    49     print(a.testTb[i])
    50 end
    51 print("------------------------5")
    52 for i=1,#Shape.testTb do
    53     print(Shape.testTb[i])
    54 end

    三.默认值

    1.使用元表设置默认值,这种方法的好处是修改元表后,会修改所有子表的默认值。

     1 Shape = {area = 0, test = 123}
     2 
     3 function Shape:New(o, side)
     4     o = o or {}
     5     setmetatable(o, self)
     6     self.__index = self
     7     side = side or 0
     8     --self.area = side * side
     9     o.area = side * side
    10     return o
    11 end
    12 
    13 function Shape:PrintArea()
    14     print("面积为 ", self.area)
    15 end
    16 
    17 local a = Shape:New(nil, 10)
    18 local b = Shape:New(nil, 10)
    19 print(a.test)
    20 print(b.test)
    21 print(Shape.test)
    22 Shape.test = 456
    23 print(a.test)
    24 print(b.test)

    2.使用New设置默认值,这种方法会使每张表有各自的值,修改元表不会对其进行影响。

     1 Shape = {area = 0, test = 123}
     2 
     3 function Shape:New(o, side)
     4     o = o or {}
     5     setmetatable(o, self)
     6     self.__index = self
     7     side = side or 0
     8     --self.area = side * side
     9     o.area = side * side
    10     o.test = 789
    11     return o
    12 end
    13 
    14 function Shape:PrintArea()
    15     print("面积为 ", self.area)
    16 end
    17 
    18 local a = Shape:New(nil, 10)
    19 local b = Shape:New(nil, 10)
    20 print(a.test)
    21 print(b.test)
    22 print(Shape.test)
    23 Shape.test = 456
    24 a.test = 111
    25 print(a.test)
    26 print(b.test)

    四.调用父类方法

     1 Shape = {}
     2 
     3 function Shape:New(o, side)
     4     o = o or {}
     5     setmetatable(o, self)
     6     self.__index = self
     7     side = side or 0
     8     o.area = side * side
     9     return o
    10 end
    11 
    12 function Shape:PrintArea()
    13     print("Shape面积为 ", self.area)
    14 end
    15 
    16 Square = Shape:New()
    17 
    18 function Square:New(o, side)
    19     o = o or {}
    20     setmetatable(o, self)
    21     self.__index = self
    22     side = side or 0
    23     o.area = side * side
    24     return o
    25 end
    26 
    27 function Square:PrintArea()
    28     print("Square面积为 ", self.area)
    29     Shape.PrintArea(self)
    30 end
    31 
    32 local a = Shape:New(nil, 10)
    33 local b = Square:New(nil, 20)
    34 print(a:PrintArea())
    35 print("-------------")
    36 print(b:PrintArea())

    五.继承中的table问题

     1 A = {}
     2 
     3 function A:New()
     4     local o = {}
     5     setmetatable(o, self)
     6     self.__index = self
     7     o.child = {}
     8     return o
     9 end
    10 
    11 function A:AddChild()
    12     table.insert(self.child, 1)
    13 end
    14 
    15 function A:Print()
    16     print(#self.child)
    17 end
    18 
    19 B = A:New()
    20 
    21 function B:New()
    22     local o = {}
    23     setmetatable(o, self)
    24     self.__index = self
    25     return o
    26 end
    27 
    28 local b1 = B:New();
    29 local b2 = B:New();
    30 b1:AddChild()
    31 b1:Print()
    32 b2:Print()
    33 b2:AddChild()
    34 b2:Print()

    如上,b1和b2共用A表中的child,而正确来说b1和b2要有各自的child,因此在B:New()中添加语句:o.child = {},输出如下:

  • 相关阅读:
    Building a flexiable renderer
    Indirect Illumination in mental ray
    我的心情
    Cellular Automata
    Subsurface Scattering in mental ray
    Shader Types in mental ray
    BSP Traversal
    我的渲染器终于达到了MR的速度
    How to handle displacement and motion blur
    说明
  • 原文地址:https://www.cnblogs.com/lyh916/p/9563319.html
Copyright © 2011-2022 走看看