hump.class¶
Class = require "hump.class"
A small, fast class/prototype implementation with multiple inheritance.
Implements class commons.
Example:
Critter = Class{
init = function(self, pos, img)
self.pos = pos
self.img = img
end,
speed = 5
}
function Critter:update(dt, player)
-- see hump.vector
local dir = (player.pos - self.pos):normalize_inplace()
self.pos = self.pos + dir * Critter.speed * dt
end
function Critter:draw()
love.graphics.draw(self.img, self.pos.x, self.pos.y)
end
List of Functions¶
Function Reference¶
-
Class.
new
()¶ -
Class.
new
({init = constructor, __includes = parents, ...}) Arguments: - constructor (function) – Class constructor. Can be accessed with
theclass.init(object, ...)
. (optional) - or table of classes parents (class) – Classes to inherit from. Can either be a single class or a table of classes. (optional)
- ... (mixed) – Any other fields or methods common to all instances of this class. (optional)
Returns: The class.
- constructor (function) – Class constructor. Can be accessed with
Declare a new class.
init()
will receive the new object instance as first argument. Any other
arguments will also be forwarded (see examples), i.e. init()
has the
following signature:
function init(self, ...)
If you do not specify a constructor, an empty constructor will be used instead.
The name of the variable that holds the module can be used as a shortcut to
new()
(see example).
Examples:
Class = require 'hump.class' -- `Class' is now a shortcut to new()
-- define a class class
Feline = Class{
init = function(self, size, weight)
self.size = size
self.weight = weight
end;
-- define a method
stats = function(self)
return string.format("size: %.02f, weight: %.02f", self.size, self.weight)
end;
}
-- create two objects
garfield = Feline(.7, 45)
felix = Feline(.8, 12)
print("Garfield: " .. garfield:stats(), "Felix: " .. felix:stats())
Class = require 'hump.class'
-- same as above, but with 'external' function definitions
Feline = Class{}
function Feline:init(size, weight)
self.size = size
self.weight = weight
end
function Feline:stats()
return string.format("size: %.02f, weight: %.02f", self.size, self.weight)
end
garfield = Feline(.7, 45)
print(Feline, garfield)
Class = require 'hump.class'
A = Class{
foo = function() print('foo') end
}
B = Class{
bar = function() print('bar') end
}
-- single inheritance
C = Class{__includes = A}
instance = C()
instance:foo() -- prints 'foo'
instance:bar() -- error: function not defined
-- multiple inheritance
D = Class{__includes = {A,B}}
instance = D()
instance:foo() -- prints 'foo'
instance:bar() -- prints 'bar'
-- class attributes are shared across instances
A = Class{ foo = 'foo' } -- foo is a class attribute/static member
one, two, three = A(), A(), A()
print(one.foo, two.foo, three.foo) --> prints 'foo foo foo'
one.foo = 'bar' -- overwrite/specify for instance `one' only
print(one.foo, two.foo, three.foo) --> prints 'bar foo foo'
A.foo = 'baz' -- overwrite for all instances without specification
print(one.foo, two.foo, three.foo) --> prints 'bar baz baz'
-
class.
init
(object, ...)¶ Arguments: - object (Object) – The object. Usually
self
. - ... (mixed) – Arguments to pass to the constructor.
Returns: Whatever the parent class constructor returns.
- object (Object) – The object. Usually
Calls class constructor of a class on an object.
Derived classes should use this function their constructors to initialize the parent class(es) portions of the object.
Example:
Class = require 'hump.class'
Shape = Class{
init = function(self, area)
self.area = area
end;
__tostring = function(self)
return "area = " .. self.area
end
}
Rectangle = Class{__includes = Shape,
init = function(self, width, height)
Shape.init(self, width * height)
self.width = width
self.height = height
end;
__tostring = function(self)
local strs = {
"width = " .. self.width,
"height = " .. self.height,
Shape.__tostring(self)
}
return table.concat(strs, ", ")
end
}
print( Rectangle(2,4) ) -- prints 'width = 2, height = 4, area = 8'
-
Class:include
(other)¶ Arguments: - other (tables) – Parent classes/mixins.
Returns: The class.
Inherit functions and variables of another class, but only if they are not already defined. This is done by (deeply) copying the functions and variables over to the subclass.
Note
class:include()
doesn’t actually care if the arguments supplied are
hump classes. Just any table will work.
Note
You can use Class.include(a, b)
to copy any fields from table a
to table b
(see second example).
Examples:
Class = require 'hump.class'
Entity = Class{
init = function(self)
GameObjects.register(self)
end
}
Collidable = {
dispatch_collision = function(self, other, dx, dy)
if self.collision_handler[other.type])
return collision_handler[other.type](self, other, dx, dy)
end
return collision_handler["*"](self, other, dx, dy)
end,
collision_handler = {["*"] = function() end},
}
Spaceship = Class{
init = function(self)
self.type = "Spaceship"
-- ...
end
}
-- make Spaceship collidable
Spaceship:include(Collidable)
Spaceship.collision_handler["Spaceship"] = function(self, other, dx, dy)
-- ...
end
-- using Class.include()
Class = require 'hump.class'
a = {
foo = 'bar',
bar = {one = 1, two = 2, three = 3},
baz = function() print('baz') end,
}
b = {
foo = 'nothing to see here...'
}
Class.include(b, a) -- copy values from a to b
-- note that neither a nor b are hump classes!
print(a.foo, b.foo) -- prints 'bar nothing to see here...'
b.baz() -- prints 'baz'
b.bar.one = 10 -- changes only values in b
print(a.bar.one, b.bar.one) -- prints '1 10'
-
class:clone
()¶ Returns: A deep copy of the class/table.
Create a clone/deep copy of the class.
Note
You can use Class.clone(a)
to create a deep copy of any table (see
second example).
Examples:
Class = require 'hump.class'
point = Class{ x = 0, y = 0 }
a = point:clone()
a.x, a.y = 10, 10
print(a.x, a.y) --> prints '10 10'
b = point:clone()
print(b.x, b.y) --> prints '0 0'
c = a:clone()
print(c.x, c.y) --> prints '10 10'
-- using Class.clone() to copy tables
Class = require 'hump.class'
a = {
foo = 'bar',
bar = {one = 1, two = 2, three = 3},
baz = function() print('baz') end,
}
b = Class.clone(a)
b.baz() -- prints 'baz'
b.bar.one = 10
print(a.bar.one, b.bar.one) -- prints '1 10'
Caveats¶
Be careful when using metamethods like __add
or __mul
: If a subclass
inherits those methods from a superclass, but does not overwrite them, the
result of the operation may be of the type superclass. Consider the following:
Class = require 'hump.class'
A = Class{init = function(self, x) self.x = x end}
function A:__add(other) return A(self.x + other.x) end
function A:show() print("A:", self.x) end
B = Class{init = function(self, x, y) A.init(self, x) self.y = y end}
function B:show() print("B:", self.x, self.y) end
function B:foo() print("foo") end
B:include(A)
one, two = B(1,2), B(3,4)
result = one + two -- result will be of type A, *not* B!
result:show() -- prints "A: 4"
result:foo() -- error: method does not exist
Note that while you can define the __index
metamethod of the class, this is
not a good idea: It will break the class mechanism. To add a custom __index
metamethod without breaking the class system, you have to use rawget()
. But
beware that this won’t affect subclasses:
Class = require 'hump.class'
A = Class{}
function A:foo() print('bar') end
function A:__index(key)
print(key)
return rawget(A, key)
end
instance = A()
instance:foo() -- prints foo bar
B = Class{__includes = A}
instance = B()
instance:foo() -- prints only foo