CoffeeScript - Classes and Inheritance


Advertisements

JavaScript does not provide the class keyword. We can achieve inheritance in JavaScript using objects and their prototypes. Every object have their own prototype and they inherit functions and properties from their prototypes. Since the prototype is also an object, it also has its own prototype.

Though the prototypal inheritance is far more powerful than classic inheritance, it is difficult and confusing for novice users.

Classes in CoffeeScript

Addressing to this problem, CoffeeScript provides a basic structure known as class which is built using the JavaScript's prototypes. You can define a class in CoffeeScript using the class keyword as shown below.

class Class_Name

Example

Consider the following example, here we have created a class named Student using the keyword class.

class Student

If you compile the above code, it will generate the following JavaScript.

var Student;

Student = (function() {
  function Student() {}

  return Student;

})();

Instantiating a class

We can instantiate a class using the new operator just like other object oriented programming languages as shown below.

new Class_Name

You can instantiate the above created (Student) class using the new operator as shown below.

class Student
new  Student

If you compile the above code, it will generate the following JavaScript.

var Student;

Student = (function() {
  function Student() {}

  return Student;

})();

new Student;

Defining a Constructor

A constructor is a function that is invoked when we instantiate a class, its main purpose is to initialize the instance variables. In CoffeeScript, you can define a constructor just by creating a function with name constructor as shown below.

class Student
  constructor: (name)->
  @name = name

In here, we have defined a constructor and assigned the local variable name to the instance variable.

The @ operator is an alias to the this keyword, it is used to point the instance variables of a class.

If we place @ before an argument of the constructor, then it will be set as an instance variable automatically. Therefore, the above code can be written simply as shown below −

class Student
  constructor: (@name)->

Example

Here is an example of a constructor in CoffeeScript. Save it in a file with the name constructor_example.coffee

#Defining a class
class Student
  constructor: (@name)->

#instantiating a class by passing a string to constructor
student = new Student("Mohammed");
console.log "the name of the student is :"+student.name

Compiling the code

Open command prompt and compile the above example as shown below.

c:\>coffee -c constructor_example.coffee

On executing the above command it will produce the following JavaScript.

// Generated by CoffeeScript 1.10.0
(function() {
  var Student, student;

  Student = (function() {
    function Student(name) {
      this.name = name;
    }

    return Student;

  })();

  student = new Student("Mohammed");

  console.log("The name of the student is :"+student.name);

}).call(this);

Executing the Code

Run the above example by executing the following command on the command prompt.

coffee constructor_example.coffee

On running, the above example gives you the following output.

The name of the student is :Mohammed

Instance Properties

Same as in objects, we can also have properties within a class. And these are known as instance properties.

Example

Consider the following example. In here, we have created variables (name, age) and a function (message()) within the class and accessed them using its object. Save this example in a file named instance_properties_example.coffee

#Defining a class
class Student
  name="Ravi"
  age=24
  message: ->
    "Hello "+name+" how are you" 

#instantiating a class by passing a string to constructor
student = new Student();
console.log student.message()

On compiling, the above code generates the following output.

// Generated by CoffeeScript 1.10.0
(function() {
  var Student, student;

  Student = (function() {
    var age, name;

    function Student() {}

    name = "Ravi";

    age = 24;

    Student.prototype.message = function() {
      return "Hello " + name + " how are you";
    };

    return Student;

  })();

  student = new Student();

  console.log(student.message());

}).call(this);

Static Properties

We can define static properties in the class. The scope of the static properties is restricted within the class and we create static functions using the this keyword or its alias @ symbol and we have to access these properties using the class name as Class_Name.property.

Example

In the following example, we have created a static function named message. and accessed it. Save it in a file with the name static_properties_example.coffee.

#Defining a class
class Student
  @message:(name) ->
    "Hello "+name+" how are you" 
console.log Student.message("Raju")

Open the command prompt and compile the above CoffeeScript file using the following command.

c:\>coffee -c  static_properties_example.coffee

On compiling, it gives you the following JavaScript.

// Generated by CoffeeScript 1.10.0
(function() {
  var Student;

  Student = (function() {
    function Student() {}

    Student.message = function(name) {
      return "Hello " + name + " how are you";
    };

    return Student;

  })();

  console.log(Student.message("Raju"));

}).call(this);

Execute the above coffeeScript in command prompt as shown below.

c:\>coffee static_properties_example.coffee

On executing, the above example gives you the following output.

Hello Raju how are you

Inheritance

In CoffeeScript, we can inherit the properties of one class in another class using extends keyword.

Example

Following is an Example of inheritance in CoffeeScript. In here, we have two classes namely Add and My_class. We inherited the properties of class named Add in the class My_class, and accessed them using the extends keyword.

#Defining a class
class Add
   a=20;b=30
   
   addition:->
     console.log "Sum of the two numbers is :"+(a+b) 

class My_class extends Add

my_class = new My_class()
my_class.addition()

CoffeeScript uses prototypal inheritance behind the scenes. In CoffeeScript, whenever we create instances, the parent class's constructor is invoked until we override it.

We can invoke the constructor of the parent class from the subclass, using the super() keyword as shown in the example given below.

#Defining a class
class Add
   constructor:(@a,@b) ->
   
   addition:=>
     console.log "Sum of the two numbers is :"+(@a+@b) 

class Mul extends Add
   constructor:(@a,@b) ->
     super(@a,@b)
   
   multiplication:->
     console.log "Product of the two numbers is :"+(@a*@b)

mul = new Mul(10,20)
mul.addition()
mul.multiplication()

Dynamic Classes

CoffeeScript uses prototypal inheritance to automatically inherit all the instance properties of a class. This ensures that classes are dynamic; even if you add properties to a parent class after a child has been created, the property will still be propagated to all of its inherited children.

class Animal
  constructor: (@name) ->

class Parrot extends Animal

Animal::rip = true

parrot = new Parrot("Macaw")
console.log "This parrot is no more" if parrot.rip

On executing, the above CoffeeScript generates the following JavaScript code.

// Generated by CoffeeScript 1.10.0
(function() {
  var Animal, Parrot, parrot,
    extend = function(child, parent) { for (var key in parent) {
      if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() {
      this.constructor = child; } ctor.prototype = parent.prototype;
      child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
    hasProp = {}.hasOwnProperty;

  Animal = (function() {
    function Animal(name) {
      this.name = name;
    }

    return Animal;

  })();

  Parrot = (function(superClass) {
    extend(Parrot, superClass);

    function Parrot() {
      return Parrot.__super__.constructor.apply(this, arguments);
    }

    return Parrot;

  })(Animal);

  Animal.prototype.rip = true;

  parrot = new Parrot("Macaw");

  if (parrot.rip) {
    console.log("This parrot is no more");
  }
  
}).call(this);  
Advertisements