Classes & O.O.
BoxLang speaks O.O. and functional tongues.
BoxLang is an Object-Oriented programming language which means that all the things we interact with inside the virtual machine are objects, which in our case we will call Classes (.bx
). Objects can hold data, called properties, and they can perform actions, called methods or functions, they can inherit from other objects, they can implement interfaces, they can contain metadata, and even act as RESTFul web services.
Remember that objects are not only data but data + behavior.
For an example of an object, think about you as a human being. You have properties/attributes like height, weight, and eye color. You have functions/methods like walk, run, wash dishes, and daydream. Different kinds of objects have different properties and functions. Some might even just be a collection of functions (utility/static/service objects) or what are referred to as stateless objects, there is no instance data that they represent.
BoxLang supports not only the traditional avenues for object orientation but also many unique constructs and dynamic runtime additions. Enjoy!
Classes and Instances
In Object-Oriented programming, we define classes which are abstract descriptions of a category or type of thing; a blueprint. In our case, we will call them classes and it defines what properties and functions all objects (instances) of that type have. You can consider them to be a blueprint of your object representation. They should have a distinct job and a single responsibility (if possible), try to avoid creating God objects.
In object-oriented programming, a God object is an object that knows too much or does too much. The God object is an example of an anti-pattern. A common programming technique is to separate a large problem into several smaller problems (a divide and conquer strategy) and create solutions for each of them. - https://en.wikipedia.org/wiki/God_object
Let's check out an example of a simple Component, User.bx
Please check out the following articles:
Notes of Interest
The attribute accessors
in the class definition denotes that automatic getters (accessors) and setters (mutators) will be created for all defined properties in the object. Also notice that the class and each property can be documented using /** **/
notation, which is great for automatic documentation generators like DocBox.
Get into the habit of inline documentation, it can go a long way for automatic generators and make you look like you can document like a machine!
Creating Instances
The User.bx class above is a representation of any user or the idea of a user. In order to bring it to life we will create an instance of it, populate it with instance data and then use it.
An instance, is a copy of that blueprint that you are bringing to life that will be stored in memory and used by the language during a set of executions. Usually via a new
or createObject()
keyword operation from another file, which can be a template or yet another class.
Please note that the new
keyword will automatically call an object's constructor: the init()
method. The createObject()
will not, you will have to call the constructor manually:
In later chapters we will investigate the concept of dependency injection. Please also note that the createObject()
function can also be used to create different types of objects in BoxLang like:
Classes
Webservices (WSDL based)
Java Objects
.NET assemblies
COM Objects
Corba
Constructors
Every object in theory should have a constructor method or a method that initializes the object to a ready state. Even if the constructor is empty, get into the habit of creating one.
Note that the constructor returns the this
scope. This is a reference of the object itself that is returned. You can also return this
from ANY other function which allows for expressive or fluently chainable methods.
By default when using the new Object()
operator, the Object's init()
function will be called for you automatically. If you use the createObject()
then the init()
is NOT called automatically for you, you will call it explicitly.
Pseudo-Constructor
The pseudo-constructor can be found in use in BoxLang and it's a unique beast. Any source code that exists between the class
declaration and the first function is considered to be the pseudo-constructor. This area of execution will be executed for you implicitly whenever the object is created, even before the implicit init()
method call. I know confusing, but here is a simple sequence: new()/createObject() -> pseudo-constructor -> init()
Component Scopes
Every class has certain visibility scopes where properties, variables and functions are attached to.
variables
- Private scope, visible internally to the class only, where allproperties
are placed in by default. Public and private function references are place here as well.this
- Public scope, visible from the outside world (can break encapsulation) public function references are placed here.static
- Same as in Java, ability to staticly declare variables and functions at the blueprint level and not at the instance level.
Component Attributes
The class
construct can also have many attributes or name-value pairs that will give it some extra functionality for SOAP/REST web services and for Hibernate ORM Persistence. Each BoxLang engine provides different capabilities. You can find all of them here: https://cfdocs.org/cfcomponent. Below are the most common ones:
accessors
- Enables automatic getters/setters for propertiesextends
- Provides inheritance via the path of the Classimplements
- Names of the interfaces it implementspersistent
- Makes the object a Hibernate Entity which can be fine tuned through a slew of other attributes.serializable
- Whether the class can be serialized into a string/binary format or not. Default istrue
.
Please note that in BoxLang you can also declare these attributes via annotations in the comments section, weird, I know!
Last updated