# BladeRunner object-oriented JS

The _Base Library_ allows you to code your application in an easy, Java-like way. This section explains how.

Traditionally, JavaScript has been seen and used as a light-weight language, not really suited for enterprise scale application development. The Caplin approach to JavaScript coding for developing applications within _BladeRunner_, has therefore been influenced a lot by Java. We’ve provided a structure that allows developers to code in a Java-like way, with concepts such as interfaces and class-based inheritance. If you were only ever using JavaScript in its more conventional, light-weight role, all this additional structure would probably seem rather over-engineered, but for enterprise-scale JavaScript it offers considerable benefits.

## Java-Based Approach

One of the conventions adopted from Java is that each class or interface should be defined in a separate file, and the files should be placed within a directory structure that matches the namespace of the class or interface. As long as the namespacing rules are obeyed, _BladeRunner’s_ **JS Bundler** will be able to locate and 'bundle' all the necessary code into the application at run-time.

## Classes and Namespacing

Classes have to be declared using their full namespace. For example: if you want to declare a class called ***_HelloWorld_ **in the *_novox_** package, you should first create a file called **_HelloWorld.js_** under the **_src/novox_** directory, within your desired location. The desired location could be an **aspect**, **blade** or suchlike. Your _HelloWorld.js_ file might contain something like this:

```js
novox.HelloWorld = function()
  {
  };

novox.HelloWorld.prototype.sayHi = function()
  {
    alert('Hello World!!');
  };
```

## General Structure

The overall structure of JavaScript in _BladeRunner_ can be summarised as follows. We’ll go into more detail on each of these further down, but it might help to give you a 'starter for ten', as it were!

* **Interfaces.** An interface is a class with a number of methods defined for it, but its methods cannot be called directly; if an interface’s method is called directly, it will throw an exception. In essence, an interface is a template for other classes that will implement it and its methods. Interfaces are created using the `caplin.core.Utility.interfaceMethod()` method.
* **Classes that Implement Interfaces.** You can create any number of classes that implement an interface (i.e. that use the interface as a template), by using the `caplin.implement()` method. In order to be properly usable, a class that implements an interface must also explicitly implement all its methods before it calls them. If you call an interface’s method without implementing it first, will just throw an exception – as it would if you called it directly. 
  * **Abstract Classes.** If you create a class that implements an interface, but doesn’t implement all of its methods, it is incomplete, and cannot be used on its own. You might want to create such a class though, in order to define shared methods for a set of classes that have certain things in common, but which differ in other ways. You would create these additional classes by extending your abstract class.
  * **Concrete Classes.** A concrete class implements an interface, and all its methods, either by implementing it directly, or by extending an abstract class, and declaring the methods that the abstract class omits. If it extends an abstract class, then by default, it will inherit the implementations of the interface methods that were declared in the abstract class.
* **Extending Classes.** A class can be extended using the `caplin.extend()` construct. The new class will inherit all the default methods declared by the class that it extended from, although it can modify them if necessary.
* **Static Classes.** A static class is declared without using the `_prototype_` element of the declaration. It is not extensible, cannot be instantiated and must be named in full, every time it is called.

## Interfaces

Declaring an interface is essentially the same as declaring a class. With interfaces though, it’s important to provide feedback when an arbitrary method has not been implemented. You can do that by using `caplin.core.Utility.interfaceMethod()`, within the body of each of your interface’s methods.

Using **_``Animal``_** as an example interface, your definition could look something like this:

```js
novox.Animal = function()
  {
  };

  novox.Animal.prototype.speak = function()
    {
      caplin.core.Utility.interfaceMethod("novox.Animal" , "speak");
    };

  novox.Animal.prototype.getGender = function()
    {
      caplin.core.Utility.interfaceMethod("novox.Animal" , "getGender");
    };

  novox.Animal.prototype.getLegCount = function()
    {
      caplin.core.Utility.interfaceMethod("novox.Animal" , "getLegCount");
    };
```

If another class implements the `Animal` interface, it must implement all its methods as well, or it will not be able to invoke them.

**For example:** if a class implements `Animal`, but does not provide an implementation for the method `speak()`, any invocation to speak will cause an exception with the message "**_Unexpected exception (This is an interface method (novox.Animal.speak))_**" being thrown to the console.

### Implementing an Interface

You can implement an interface using the `caplin.implement()` method. As you might expect, you can use this invocation to implement as many interfaces as you wish. If we wanted to declare a `Quadruped` class that implements the `Animal` interface, we could do it like this:

```js
novox.Quadruped = function(sGender)
  {
    this.m_sGender = sGender;
  };

  caplin.implement(novox.Quadruped, novox.Animal);

  novox.Quadruped.prototype.getLegCount = function()
    {
      return 4;
    };

  novox.Quadruped.prototype.getGender = function()
    {
      return this.m_sGender;
    };
```

Note that it’s important to implement the interface _before_ any method declarations for it to work properly. It’s also important to provide the actual JavaScript constructor functions to `caplin.implement()` rather than the function names as strings. You may also notice the `Quadruped` class hasn’t implemented the `speak()` method, which effectively makes this an _abstract class_.

## Extending a Class

As `Quadruped` is an abstract class, we are going to need to extend it to provide a concrete implementation. Extending a class is very similar to implementing an interface; you do it by using the `_caplin.extend()_` construct. You should follow the same rules as for `caplin.implement()` when using this construct, declaring the class extension before you declare any of its methods.

Going back to our example, let’s extend `Quadruped` to give us two concrete classes of `Quadruped`: `_Cat_` and `_Dog_`.

```js
novox.Dog = function(sGender)
  {
  };
  caplin.extend(novox.Dog, novox.Quadruped);

  novox.Dog.prototype.speak = function()
    {
      alert("Woof!");
    };

novox.Cat = function(sGender)
  {
  };
  caplin.extend(novox.Cat, novox.Quadruped);

  novox.Cat.prototype.speak = function()
    {
      alert("Meow!");
    }
```

By extending the `Quadruped` class and implementing the remaining method from the `Animal` interface, each of these new classes is complete and we could create instances of them.

### Calling Super-Methods

Using the JavaScript methods `_call()_` and `_apply()_` allows us to call super-constructors and methods whilst retaining the correct "this" pointer.

Ideally, our `Dog` and `Cat` constructors would both pass on their genders to the `Quadruped` super-constructor, so we could add a line to each constructor so that this happens:

```js
novox.Dog = function(sGender)
  {
    novox.Quadruped.apply(this, arguments);
  };

...

novox.Cat = function(sGender)
  {
    novox.Quadruped.apply(this, arguments);
  };
```

If we added any additional arguments at a later date, using the `arguments` keyword ensures that they would all be passed back to the `Quadruped` super-constructor without having to explicitly add them to the `apply()` method in each constructor.

### Overriding Super-methods

By default, our cats and dogs all have four legs, a feature that they inherit – not unreasonably – from the `Quadruped` class. If we wanted to allow for the occasional three-legged dog we might encounter however, the following code would allow us to do this, whilst still being able to call the super-method, allowing normal dogs to retain their traditional allocation of legs.

```js
novox.Dog.prototype.getLegCount = function()
  {
    if (this.is3LeggedDog())
      {
        return 3;
      }
    return novox.Quadruped.prototype.getLegCount.call(this);
  };
```

## Static Classes and Enums

It may be useful to provide static classes and enums within your application, to complement particular classes and interfaces. You can write static classes and enums by omitting the `prototype` from property and method declarations. For example: we may want to provide an `_AnimalGender_` enum to be used in conjunction with the `Animal` interface:

```js
novox.AnimalGender = function()
  {
  };
  novox.AnimalGender.MALE = "male";
  novox.AnimalGender.FEMALE = "female";
```
