display classes
https://www.lianja.com/doc/index.php/DISPLAY_CLASSES
list classes
https://www.lianja.com/doc/index.php/LIST_CLASSES
All Lianja UI Framework Classes provide integrated data binding to the underlying Lianja embedded database (the Controlsource property).
tb = createObject("textbox") // table.column tb.controlsource = "customer.lastname" // a function call tb.controlsource = "myfunc()" // a macro expression tb.controlsource = "{expression}"
https://www.lianja.com/doc/index.php/Understanding_Data_Binding
myObject = createobject("MyClass")
https://www.lianja.com/doc/index.php/CREATEOBJECT()
// myclasslib.vcp define class Product as custom productname = "Lianja App Builder" version = "1.0" proc init(arg1) ? etos(arg1) endproc proc getver ? this.version endproc enddefine // end of myclasslib.vcp oProduct = newobject("Product","myclasslib","Hello World")
https://www.lianja.com/doc/index.php/NEWOBJECT()
define class product as custom productname = "Lianja App Builder" version = "3.4" proc init(arg1) ? etos(arg1) endproc proc getver ? this.version endproc enddefine oProduct = new product("Hello World") oProduct.getver() ? oProduct.productname
https://www.lianja.com/doc/index.php/NEW_Operator
set classlib to myclasses1 ? set([classlib]) list classes ? class_exists("mybutton1")
https://www.lianja.com/doc/index.php/CLASS_EXISTS()
set classlib to myclasses list classlib
https://www.lianja.com/doc/index.php/LIST_CLASSLIB
set classlib to myclasses currclasslib = set('classlib')
https://www.lianja.com/doc/index.php/SET_CLASSLIB
nHierarchy = aclass(aHierarchy,myObject)
https://www.lianja.com/doc/index.php/ACLASS()
define class myclass as custom myprop = "Hello World" enddefine myobject = createobject("myclass") Messagebox(myobject.myprop) addproperty(myobject, "myprop2", "goodbye") // Or: myobject.addproperty("myprop2", "goodbye") Messagebox(myobject.myprop2) removeproperty(myobject, "myprop2") // Or: myobject.removeproperty("myprop2")
https://www.lianja.com/doc/index.php/ADDPROPERTY()
define class Product as custom productname = "Lianja App Builder" version = "1.0" enddefine oProduct = createobject("Product") ? amembers(myarray,oProduct) display memory
https://www.lianja.com/doc/index.php/AMEMBERS()
define class myClass as custom productname = "Lianja App Builder" version = "1.0" enddefine
https://www.lianja.com/doc/index.php/DEFINE_CLASS
define class myclass1 as custom property firstname property lastname enddefine define class myclass2 as custom property firstname property lastname enddefine define class myclass3 as custom property firstname property lastname property midinitial enddefine o1 = new myclass1() o2 = new myclass2() o3 = new myclass3() o1.firstname = "John" o1.lastname = "Johnson" o2.firstname = "Jack" o2.lastname = "Johnson" o3.firstname = "John" o3.lastname = "Johnson" ? compobj(o1,o2) // Returns .F. as firstname property has different values o2.firstname = "John" ? compobj(o1,o2) // Returns .T. as properties and values identical ? compobj(o1,o3) // Returns .F. as although firstname and lastname properties are identical, // o3 has a midinitial property and o1 does not
https://www.lianja.com/doc/index.php/COMPOBJ()
customer = object("custname" => "A Buyer Ltd.", ; "currentorder" => object("ord_id" => "00001", "ord_date" => date(),"ord_total" => 1599,; "orderitems" => object("10 reams A4 paper","500 business cards",; "500 black ballpoint pens"))) display memory Memory Variables: ------------------------ private(2): CUSTOMER Object (refptr OBJECT, refcnt 1) .CUSTNAME Character 'A Buyer Ltd.' .CURRENTORDER Object (refptr OBJECT, refcnt 0) .ORD_ID Character '00001' .ORD_DATE Date 12/21/2012 .ORD_TOTAL Numeric 1599 (1599.000000000) .ORDERITEMS Object (refptr OBJECT, refcnt 0) [1] Character '10 reams A4 paper' [2] Character '500 business cards' [3] Character '500 black ballpoint pens' ** Total of ** 10 variables defined and 864 bytes use ** Total of ** 10 variables defined and 864 bytes used.
https://www.lianja.com/doc/index.php/OBJECT()
class myclass endclass obj1=new myclass() obj1.save("file1") obj2=loadobject("file1") // or for an existing object obj1.load("file1")
https://www.lianja.com/doc/index.php/LOADOBJECT()
class myclass ... endclass obj1 = new myclass() saveobject(obj1,"file1") // or obj1.save("file1")
https://www.lianja.com/doc/index.php/SAVEOBJECT()
define class myclass as custom myprop = "Hello World" enddefine myobject = createobject("myclass") Messagebox(myobject.myprop) addproperty(myobject, "myprop2", "goodbye") // Or: myobject.addproperty("myprop2", "goodbye") Messagebox(myobject.myprop2) removeproperty(myobject, "myprop2") // Or: myobject.removeproperty("myprop2")
https://www.lianja.com/doc/index.php/REMOVEPROPERTY()
scatter name oNewData scatter oldvalues name oOldData oChangedData = diffobj(oNewData, oOldData)
https://www.lianja.com/doc/index.php/DIFFOBJ()
class Box procedure Draw messagebox("This is the parent Draw Method") endproc && Draw endclass class Dialog1 of Box procedure Draw messagebox("This is the object Draw Method") // call the Draw method of the Box parent class dodefault() endproc && Draw endclass oDIALOGOK = createobject("Dialog1") oDIALOGOK.Draw() release oDIALOGOK
https://www.lianja.com/doc/index.php/DODEFAULT()
define class Product as custom productname = "Lianja App Builder" version = "1.0" proc getver ? this.version endproc enddefine oProduct = createobject("Product") oProduct.getver() ? pemstatus(oProduct,"productname",5) // .T. ? pemstatus(oProduct,"getver",5) // .T. ? pemstatus(oProduct,"notthere",5) // .F.
https://www.lianja.com/doc/index.php/PEMSTATUS()
raiseevent(myobj,"click")
https://www.lianja.com/doc/index.php/RAISEEVENT()
with oProduct .productname = "Lianja App Builder" .productversion = "1.0" .productyear = "2013" endwith
https://www.lianja.com/doc/index.php/WITH
open database southwind select * from example into object adynamic ? is_object(adynamic) .T.
https://www.lianja.com/doc/index.php/IS_OBJECT()
open database southwind select * from shippers into object shipobj print_r(shipobj)
Dynarray (refcnt=1) ( [row1] => Dynarray (refcnt=1) ( [shipperid] => 1 [companyname] => Speedy Express [phone] => (503) 555-9831 ) [row2] => Dynarray (refcnt=1) ( [shipperid] => 2 [companyname] => United Package [phone] => (503) 555-3199 ) [row3] => Dynarray (refcnt=1) ( [shipperid] => 3 [companyname] => Federal Shipping [phone] => (503) 555-9931 ) )
class NullData dynamic property mCHARACTER property mNUMERIC endclass oNULLDATA = new NullData() oNULLDATA.mCHARACTER = "" oNULLDATA.mNUMERIC = 0 oNULLDATA.mLOGICAL = .F. print_r(oNULLDATA) // or alternatively just echo oNULLDATA
Object (refcnt=1) ( [mcharacter] => [mnumeric] => 0 [mlogical] => False )
https://www.lianja.com/doc/index.php/PRINT_R()
define class myclass as custom myprop = "Hello World" enddefine myobject = createobject("myclass") Messagebox(myobject.myprop) addproperty(myobject, "myprop2", "goodbye") // Or: myobject.addproperty("myprop2", "goodbye") Messagebox(myobject.myprop2) removeproperty(myobject, "myprop2") // Or: myobject.removeproperty("myprop2")
https://www.lianja.com/doc/index.php/A_Lianja_Primer
To define a class use the following syntax.
define class myclass // class members enddefine
Then, to create an object based on this class use the following syntax.
myobject = new myclass()
Or alternatively.
myobject = createobject("myclass")
Properties
An object has certain properties, or attributes that are specific to the object. Properties are the equivalent of variables that can only be accessed by referencing them inside an object. By encapsulating the data (variables) and procedures within a class, programming becomes less error prone and applications easier to maintain.
Objects you create in Lianja have properties that are determined by the class the object is based on. As Lianja is a dynamic language, classes in Lianja allow properties and methods to be added at run time.
define class myclass myprop = "hello world" enddefine myobject = new myclass() echo myobject.myprop // displays "hello world"
Properties defined within classes can be simple variables, fixed arrays, dynamic arrays or objects.
Methods
Methods are procedures that are associated with objects. Methods are different from normal Lianja procedures in that they are bound with an object and are called differently from the way normal Lianja procedures are called.
define class myclass myprop = "hello world" procedure mymethod() echo myprop endproc enddefine myobject = new myclass() myobject.mymethod() // displays "hello world"
Interface Methods
Interface Methods are template procedure definitions that must be implemented in any derived classes.
define class myclass myprop = "hello world" public procedure mymethod() interface enddefine myobject = new myclass() myobject.mymethod() // throws an error "Interface method not defined" define class myclass2 as myclass procedure mymethod() echo "hello world" endproc enddefine myobject = new myclass2() myobject.mymethod() // displays "hello world"
Member access control modifiers
You can ‘hide’ properties and methods using the access control modifiers protected, hidden, private, or static.
define class myclass private myprop = "hello world" public procedure mymethod() return myprop public static procedure mystaticmethod() endproc enddefine myobject = new myclass() // throws an error as "myprop" is private and can only be accessed by methods inside the class echo myobject.myprop myobject = new myclass() // this will work. displays "hello world" echo myobject.mymethod()
Constructors and Destructors
Lianja allows developers to declare constructor and destructor methods for classes. Classes which have a constructor method called init call this method on each newly-created object, so it is suitable for any initialization that the object may need before it is used.
define class myclass procedure init() // insert your own constructor code here endproc enddefine obj = new myclass() // the init() method is called with no arguments
You can pass arguments to the constructor method when the object is created.
define class myclass public name public title procedure init(pname, ptitle) name = pname title = ptitle endproc enddefine obj = new myclass("joe", "developer") // the init() method is called with arguments
Similarly, Lianja uses a destructor concept similar to that of other object-oriented languages, such as Java. The destructor method will be called as soon as all references to a particular object are removed or when the object is explicitly destroyed or in any order in shutdown sequence. The Lianja destuctor method is called destroy.
define class myclass procedure destroy() // insert your own destructor code here endproc enddefine obj = new myclass() obj = null // the destroy() method will be called
Class inheritance and subclassing
There are many benefits of inheritance with Lianja, the most common is simplifying and reducing instances of redundant code. Lianja supports multiple levels of inheritance. A class that inherits a parent class is said to be a ‘subclass’ of the parent.
define class product public name public price procedure init(cName, nPrice) // constructor name = cName price = nPrice endproc procedure display() ? "Product name is " + this.name + ", price is " + str(this.price) endproc enddefine define class food extends product private weight enddefine define class car extends product private color enddefine define class motorbike extends product private size enddefine // now define a vehicle class that inherits from multiple classes (car and motorbike) define class vehicle extends car, motorbike public manufacturer = "Ford" public yearDesigned procedure init(cName, nPrice) // constructor manufacturer = cName price = nPrice endproc procedure display() ? "Manufacturer is " + this.manufacturer + ", price is " + str(this.price) endproc enddefine // create a new object myobject = new vehicle("Ford", 20000) myobject.display() // displays "Manufacturer is Ford, price is 20000 myobject = new motorbike("Honda", 1500) myobject.display() // displays "Product name is Honda, price is 1500
Overriding methods
As can be seen by the above example of class inheritance, you can override methods of parent classes that you inherit. If you want to call the parent class method of the same name from within a subclass, then use the dodefault() method. Note that because Lianja handles multiple inheritance, and because a subclass can only have one ‘parent’ the last class inherited is denoted as the parent and is called by dodefault().
// now define a vehicle class that inherits from multiple classes (car and motorbike) define class vehicle extends car,motorbike public manufacturer = "Ford" public yearDesigned proc init(cName, nPrice) // constructor manufacturer = cName name = cName price = nPrice endproc proc display() dodefault() // calls the 'display()' method in the parent class 'product' ? "Manufacturer is " + this.manufacturer + ", price is " + str(this.price) endproc enddefine
Scope resolution operator
The scope resolution operator :: can be used to reference static methods and properties in classes or those in the super class.
define class myclasslib public static mydata = array() public static proc display(arg) echo arg endproc enddefine
We can call the display method without instantiating an object because it is declared static e.g.
myclasslib::display("hello world")
We can access “mydata” without instantiating an object because it is declared static e.g.
myclasslib::mydata["key"] = "value"
Special variables
There are several special built-in object variables that can be used.
Object | Description |
---|---|
this | A reference to the currently executing object |
Iterating through object properties
You can iterate over the properties of an object using the foreach command like this.
// create a new object myobject = new myclass() // iterate over its properties foreach myobject as name => value echo "name=" + name + ", value=" + value // displays "name=MYPROP, value=hello world" endfor
Dynamically adding and removing properties runtime
As Lianja is a dynamic language, object properties can be added and removed dynamically at runtime.
// create a new object myobject = new myclass() // extend it by adding a property at runtime myobject.addproperty("date", date()) // now remove it myobject.removeproperty('date')
Dynamically assigning methods at runtime
As Lianja is a dynamic language, methods can be assigned to objects dynamically at runtime.
// create a new object myobject = new myclass() // dynamically add a method procedure mynewmethod() echo "hello world" endproc myobject.newmethod = mynewmethod myobject.newmethod() // displays "hello world"
Runtime data-type checking
define class myclass public myprop as character = "hello world" public procedure mymethod() return myprop static procedure mystaticmethod() endproc enddefine // create a new object myobject = new myclass() myobject.myprop = "this is data" // works ok myobject.myprop = 10 // throws an error because we defined "myprop as character"
The life of an object
Lianja uses object reference counting to handle automatic garbage collection.
When an object is created its reference count is set to 1. All assignments of objects to other variables or procedure/function arguments cause the reference count to be incremented. An object is released from memory (dereferenced) when its reference count reaches zero.
To dereference an object you simply assign another value to it. e.g.
// create a new object (and set its reference count to 1) myobject = new myclass() // now free up the object. This will decrement the reference count associated with the object. // When the reference count is 0 then the object will be released from memory (dereferenced). myobject = null // In this example the object is not released as it is still referenced by 'myvar' myobject = new myclass() myvar = myobject myobject = null // now it will be released myvar = null
If an object property (variable) is an object reference, when the object containing the property (variable) is released (dereferenced) than the reference count of all object variables is decremented, and when the reference count reaches zero, then that object is released from memory.
Writing and using class libraries
Once you have completed the development of your class library you can use the classes within your programs like this.
require_once("myclasslib")
https://www.lianja.com/doc/index.php/Lianja_Object-Oriented_Programming
define class myclass as custom myprop = "Hello World" enddefine myobject = createobject("myclass") Messagebox(myobject.myprop) addproperty(myobject, "myprop2", "goodbye") // Or: myobject.addproperty("myprop2", "goodbye") Messagebox(myobject.myprop2) removeproperty(myobject, "myprop2") // Or: myobject.removeproperty("myprop2")
https://www.lianja.com/doc/index.php/A_Recital_Primer