Introduction

Object interfaces allow you to create code which specifies which methods a class must implement, without having to define how these methods are handled. Interfaces are defined using the Interface function, in the same way as a standard class, but without any of the methods having their contents defined.

JOII also allows you to define public properties besides methods because JOII generates getters and setters for public properties. Instead of defining every getter and setter method in an interface, you can simply define the property instead.

All properties and methods declared in an interface must be public; this is the nature of an interface.

var IPerson = Interface('IPerson', {
    'public string name'  : '',
    'public string email' : '',

    /**
     * Returns true if the given name and email matches
     * the data in this object.
     *
     * @param  string name
     * @param  string email
     * @retrun boolean
     */
    'public matches(string, string)'      : function(name, email) { }
});

implements

To implement an interface, the implements parameter is used in the parameters of a class definition. All properites and methods of the interface must be implemented within a class. Failure to do so will result in an error. Classes may implement multiple interfaces if desired by using an array notation.

Methods must match the parameter type signature defined in the interface.

var Person = Class({ implements: IPerson }, {
    'public string name'  : '',
    'public string email' : '',

    /**
     * @see IPerson.matches
     */
    'public matches(string, string)' : function(name, email) {
        return this.name === name
            && this.email === email;
    }
});

Function signatures and property metadata must be exactly the same as how they are defined in the interface the class is implementing.

The following example throw an error when the class is instantiated, because the parameter count of the function doesn't match the function signature from the interface.

var Person = Class({ implements: IPersion }, {
    // ...
    'public matches(string)' : function(name) {
        // ...
    }
});

Inheritance

Just like classes, interfaces may be extended using the extends parameter. If a method or property exists in both interface definitions, their metadata and signatures must be exactly the same, otherwise an error is thrown.

var ILoggable = Interface({
    // Interface body ...
});

var IConsole = Interface({ extends: ILoggable }, {
    // Interface body ...
});

Implementing multiple interfaces

Multiple interfaces can be implemented on a class using an array notation.

var MyConsole = Class({ implements: [IConsole, ILoggable] }, {
    // Class body ...
});

instanceOf

Checking the type of an instantiated object can be done using the instanceOf method.

var MyConsole = Class({ implements: IConsole }, {
    // Class body ...
});

var my_console = new MyConsole();

my_console.instanceOf(MyConsole); // true
my_console.instanceOf(IConsole);  // true
my_console.instanceOf(ILoggable); // true