The objectoriented class provides two functions which allows a more objectoriented like design using lua functions.
It implements a simple inheritance model. An object is a table with a metatable which includes all class information.
All functions from this class are available as global variables with the same name.
class "Foo" -- a simple class print (Foo) -- output: [Class: Foo] fobj = new(Foo) -- creates a new object of type foo print(fobj) -- print out our class object -- output: [Object: Foo 3]-- overfloating printing function now function Foo:toString() return "Foo object printout!" end print(fobj) -- will print "Foo object printout!"
-- creating a class that is derived from Foo class "Test" : extends "Foo" tobj = new(Test) print(tobj) -- will also print "Foo object printout!", -- because the toString function is derived from "Foo"
The constructors have the same name as the class has. The default constructor will delegate its call to the parent's constructor, however not so if the constructor is overloaded.
Calling the parent constructor is being done by calling its classname like a method.
class "Foo" function Foo:Foo (v1,v2) print("Foo constructor",v1,v2) endCalling the constructors is done by calling the parent's method. This can be problematic in some situations, but these are not real world examples (i.e. if the object has a variable with a name of a parent's class). Such situations can also be avoided either by not using capital letters for object variables while saving them for class names (which is similiar to Java's naming convention).class "Bar" : extends "Foo" new(Bar,1,2) -- will delegate the constructor call to -- Foo:Foo, passing the arguments 1,2 as v1 and v2, -- resulting in a printout which looks like this: -- Foo constructor 1 2
class "Foo" function Foo:Foo () Foo:Object () -- call the constructor of Object -- as every object is derived from this class end
The function 'new', which acts as a constructor is compatible with older code - if a table that is passed as class has a field named 'new', it will accept it as argument and will call this function with the passed table as first argument and returns its return.
This allows us to use the 'new' constructor also for GUI code:
btn = new(Button,10,30,20,100,"Button")
The default parent class is the Object class, a class that implements some basic operations.
The classes are also derived from the Object type - extending the Object class with additional functions (which is always possible) will also result in changing the class objects.
Any variable (functions are variables) can be defined any time. If a request on an object for a variable is made, it will return its variable value or will look in the class (or parent class and so on) if the variable is defined there. Accessing nil values is the worst case, since the whole class tree is looked up. Avoid nil value access by setting a variable value to false, if it is looked up more than once and turns out to be a performance bottleneck.
Example:
class "Foo" obj = new (Foo)Variables in classes can be used as default values, as any object that has no such variable defined will automaticly return the value of the class' variable. Variables are inherited to all its child classes, also to objects that have been defined earlier.print(obj.x) -- prints nothing or nil Foo.x = 10 print(obj.x) -- prints 10 obj.x = "bar" print(obj.bar) -- prints "bar" obj.x = nil print(obj.x) -- prints 10 Foo.x = nil print(obj.x) -- prints nothing again
When a class is extended by another class, it can always redefine a function, i.e.
class "Foo" function Foo:dosomething () print "do something foo" endWe can also overload or redefine functions when objects have already been created. All objects will call automaticly the new function code.class "Bar" : extends "Foo" function Bar:dosomehting() print "do something bar" end
However, objects can also overload functions or variables:
class "Foo" function Foo:dosomething () print "do something foo" endo = new (Foo) function o:dosomething() print "Object code" end print(o:dosomething) -- prints out "Object code"
Classes can be defined inside other tables:
somewhere = {} class ("Foo",somewhere) obj = new (somewhere.Foo)The default space is _G, which is why every class is automaticly available in the global table.class ("Bar",somewhere) : extends (somewhere.Foo)
creates an object and calls class[classname](obj,...)
returns the parent of the class or none if it is the Object class.