Guest User

protometaclass

a guest
Jan 11th, 2021
281
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 3.26 KB | None | 0 0
  1. -- Point Class
  2.  
  3. -- Prototype of the Point class
  4. -- If instance of class Point or instance of a class that inherits from this has no value, it will look here
  5. local Point = { name = "Point", x = 0, y = 0 }
  6.  
  7. -- What now was a prototype table is now both a prototype and a metatable
  8. -- Once indexed, it will look inside of itself and make things like __tostring and other metaevents work
  9. Point.__index = Point
  10.  
  11. -- The constructor function to create a new instance of class Point
  12. function Point:new(x, y)
  13.     -- We override the predefined `self` variable pointing to `Point` table, and treat it like a new instance, THIS IS A GIMMICK
  14.     self = {}
  15.    
  16.     -- Put some data into the instance depending on user input while remembering that if those are `nil` they'll use values in the `Point` prototype
  17.     self.x = x
  18.     self.y = y
  19.    
  20.     -- Assign the newly created instance to the `Point` table to use it as a metatable and a prototype
  21.     return setmetatable(self, Point)
  22. end
  23.  
  24. -- One of many metaevents, allowing us to nicely represent our object
  25. function Point:__tostring()
  26.     return string.format("[%s] X:%d Y:%d", self.name, self.x, self.y)
  27. end
  28.  
  29. function Point:setX(x)
  30.     -- Assign OR remove (if `nil` is passed) the value from `x` key of the instance
  31.     self.x = x
  32. end
  33.  
  34. function Point:getX()
  35.     -- If the instance holds `x`, return it, if not return the `x` value from `Point` prototype or if it doesn't have it, return nil
  36.     return self.x
  37. end
  38.  
  39.  
  40. -- Rectangle Class
  41.  
  42. -- Like previously with `Point`, we create a prototype table, but this time we know that we'll be inheriting from the `Point` class
  43. -- so there's no need to define `x` and `y` variables
  44. local Rectangle = { name = "Rectangle", w = 0, h = 0 }
  45.  
  46. -- Make querying this object look in itself
  47. Rectangle.__index = Rectangle
  48.  
  49. -- This is where inheritance really happens, after instance of `Rectangle` looked in itself, then the `Rectangle` prototype (because of the line above),
  50. -- make it look in the `Point` prototype / metatable
  51. setmetatable(Rectangle, { __index = Point })
  52.  
  53. -- If this was not defined, calling `Rectangle:new()` would simply result in `Point:new()` being called
  54. function Rectangle:new(x, y, w, h)
  55.     -- Create instance of the `Point` class and pass in variables from our new constructor
  56.     self = Point:new(x, y)
  57.    
  58.     -- Define extra stuff this class needs, as before it will look in the `Rectangle` prototype and then the `Point` prototype
  59.     self.w = w
  60.     self.h = h
  61.    
  62.     -- Assign the instance as part of the `Rectangle` class, to use it's methods and prototype
  63.     return setmetatable(self, Rectangle)
  64. end
  65.  
  66. -- Override the `Point` __tostring and include extra stuff from this class
  67. function Rectangle:__tostring()
  68.     return string.format("[%s] X:%d Y:%d W:%d H:%d", self.name, self.x, self.y, self.w, self.h)
  69. end
  70.  
  71. function Rectangle:setW(w)
  72.     -- Assign new value to the instance
  73.     self.w = w
  74. end
  75.  
  76. function Rectangle:getW()
  77.     -- As before, look in self, `Rectangle` prototype and `Point` prototype, even though `Point` shuld never have it defined
  78.     return self.w
  79. end
  80.  
  81. -- Testing:
  82. local p = Point:new(1, 2)
  83. print(p) --> [Point] X:1 Y:2
  84. p:setX(123)
  85. print(p:getX()) --> 123
  86.  
  87. local r = Rectangle:new()
  88. print(r:getX()) --> 0 (got from the `Point` prototype)
  89. r:setX(777)
  90. r:setW(999)
  91. print(r) --> [Rectangle] X:777 Y:0 W:999 H:0
Advertisement
Add Comment
Please, Sign In to add comment