Classing{js} Tutorial

Creating Classes

How to create Classes?

This what Classing{js} is all about , classes. Creating a class is very simple task , just call the function classing.Class

Class
classing.Class(defintion)
defintion Object

The defintion of the class

returns _classPattern Function

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
});
				

Filling your Class

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)

Reminder

Note that the Class defintion is just a regular javascript object , and that the access modifers are simply proprties of this object. So make sure you don't forget the comma ',' between every access modifer and the other in case you wrote more than one modifier.

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.

Attributes

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

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;
			}
		])
	}
});
				

Proprties

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.

Notice

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 Objects

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");