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 = {},输出如下:

  • 相关阅读:
    Android 图片圆角、图片圆形【转载:https://github.com/SheHuan/NiceImageView】
    fragment中嵌套listview,切换时数据出现重复加载
    fragment中嵌套listview,切换时数据出现重复加载
    Android让View的显示超出父容器
    ZooKeeper
    Redis
    kafka
    性能优化一
    RK Android7.1 禁用 USB触摸
    RK Android7.1 使用POWER按键才能开机
  • 原文地址:https://www.cnblogs.com/lyh916/p/9563319.html
Copyright © 2011-2022 走看看