This what Classing{js}
is all about , classes. Creating a class is very simple task , just call the function classing.Class
The defintion of the class
the created class
The easiest way to start is by writing the pattern in the follwing code and then continue with writing the defintion of your class:
var ClassName = classing.Class({ //Your defintion goes here });
before writing your class' components , you need to define the access level of these components. Assigning an access level to some components is done by placing them into one of the three access modifier objects : private , protected , or public
The access modifers of Classing{js}
follows the convetion of C++, which is that all the components of a certain access level are clustered together in a block specified by the access modifier (Unlike Java or C# in which every component is preceeded by the access modifier).
In Classing{js}
a block specifying an access level is writtenn as an object named with the related access modifier. For better understanding , take a look at this code :
var Test = classing.Class({ private : { //Your private compnents go here }, protected : { //Your protected components go here }, public : { //Your public components go here } });
You can ,of course, write one , two or all the three access modifers in your class (or you could write nothing if you want your class empty)
Now, you can start filling in your components , each inside its desired access level , in the same way you write proprties in a regular javascript object (again, don't forget the commas)
Here's an example of a full class :
var Person = classing.Class({ private : { counter:Static(0), name : null, }, public : { getCount : Static(function(){return Person.counter;}), Construct : function(){ Person.counter++; }, Name : { get : function() { return this.name; }, set : function(value) { this.name = value; } } } });
Now, we'll spend some time going through what you can put as a component for your class.
an attribute is a component which is not a method or a property (a property is a component that has a getter and a setter, as we'll know shortly). An attribute is simply written as :
attributeName : attributeValue
If you want to make this attribute static , just wrap the attributeValue
with the function classing.Static
(you could also use the global shortcut Static
)
attributeName : Static(attributeValue)
Here is an exmaple of a class with two attributes , a protecetd static attribute called ClassName, and a public non-static attribute called Id.
var AllAttributes = classing.Class({ protected : { ClassName : Static("AllAttributes") }, public : { Id : null } })
The attribute could be intialized to any value of any type but there's a little limitation on non-static attributes. A non-static attributes cannot be intialized to an object, doing so will throw an error.
var Matrix = classing.Class({ private : { internalArray : new Array() //Error } });
This limitation can be overcame by intially setting the attribute to null , then resetting it to the desired object inside the constructor of the class, like in the following example:
var Matrix = classing.Class({ private : { internalArray : null }, Construct : function() { this.internalArray = new Array(); } });
Methods are simply functions. They are defined in the same way used in regular javascript objects. They can be regular function or Classing{js}
overloaded functions, and like attributes if a method is desired to be static it's just wraped with the Static
function.
var Employee = classing.Class({ private : { counter : Static(0), hoursWorked : 0, hourlyRate : 10 }, public : { Construct : function() { Employee.counter++; }, getEmployeesCount : Static(function(){return Employee.counter}), calculatePayment : function() { return this.hoursWorked * this.hourlyRate; }, incraseHoursWorked : function () { this.hoursWorked++;}, changeHourlyRate : Function.create(xTyped , [ types(Number), function(newVal) { if(newVal > 0) { this.hourlyRate = newVal; } } ]) } });
As it appears in the above example. accessing any non-static component of the class inside one of its methods is done through this.componentName
, while accessing static components is done through className.componentName
The constructor function is a special method of the class, identified with the name Construct
. the constructor function gets called upon the creation of the object and cannot be invoked again. If you didn't write a constructor function for your class , a default (0-arguments) constructor will be automatically generated for the class. On the other hand , if you did define a constructor function , the default constructor will not be automatically generated and you must write it yourself. Like any other method , the constructor could be a regular function or Classing{js}
overloaded functions and follows the same rules in accessing the class' components.
A constructor can be in any access level. A class with a private constructor cannot be instantiated or extended. A class with a protected constructor cannot be instantiated but can be extended.
To create a copy constructor ,use the typed overloading mode of Function.create
and add an instance with an associated type of classing.xSelf
(or the global shortcut xSelf
) which points the class being created (Do Not use the class name in the copy constructor, doing so will throw an error)
Here's an example of a class with a default , a 1-argument and a copy constructors
var Human = classing.Class({ private: { age : 0 }, public: { Construct : Function.create(xTyped , [ types(), //Default function(){}, types(Number), //1-argument function(a) { if(a >= 0) { this.age = a; } }, types(xSelf), //Copy function(other) { this.age = other.age; } ]) } });
A property is a component that is defined with a getter and a setter. It's used to manipulate the attributes of the class (specially those with restricted access levels). It's defined as a regular javascript object with two functions named get and set
propertyName : { get : function(){...}, //the getter function set : function(value){...} , //the setter function }
Like attributes and methods , if a property is desired to be static it's just wrapped with the Static
function. Here is an example of a class that contains three proprties, one of them is static.
var PhoneBookRecord = classing.Class({ private : { count : Static(0), phoneNum : null, name : null }, public : { Construct : Function.create(xTyped , [ types(String , String), function(name , number) { PhoneBookRecord.count++; var NumPattern = new RegExp(/^\d{3}-\d{7}$/); var NamePattern = new RegExp(/^[A-Z][a-z]* [A-Z][a-z]*$/); if(NumPattern.test(number) && NamePattern.test(name)) { this.name = name; this.phoneNum = number; } } ]), NumberOfRecords : Static({ get : function() { return PhoneBookRecord.count; }, set : function(value){} }), PhoneNumber : { get : function() { return this.phoneNum; }, set : function(value) { var pattern = new RegExp(/^\d{3}-\d{7}$/); if(pattern.test(value)) { this.phoneNum = value; } } }, Name : { get : function(){ return this.name; }, set : function(value) { var pattern = new RegExp(/^[A-Z][a-z]* [A-Z][a-z]*$/); if(pattern.test(value)) { this.name = value; } } } } });
the NumberOfRecords
property is a static property that returns the value of the static attribute count
, which represents the number of records created so far, and because the setter of NumberOfRecords does nothing, assigning a new value to NumberOfRecords will change nothing.
The Name
property is used to get or set the attribute name
asocciated with the record. the setter function of Name performs a test before assigning a new value to the attribute name. the test checks if the new value is string of capital intials first and last name seperated by a whitespace. If the new value passes the test, it's assigned to name. If not , the value of name remains the same. A similar proccess happens with the Number
property that manipulates the phoneNum
attribute.
You can't call a non-static component from a static context, e.g. you can't access a non-static attribute from a static method. On the other hand, you can access static components from non-static context.
Instantiating an object of class you created through Classing{js} Class
is done in the same way any object in any language is instantiated , using the new
keyword.
To create a new PhoneBookRecord
we write:
var record1 = new PhoneBookRecord("John Doe" , "102-3456789");