Type Script Language Features – Classes, Inheritance & Overriding


ANOOP MADHUSUDANAN

Vote on HN

Type Script brings a lot more structure and object oriented goodness to JavaScript, thought under the hood it is just a Syntax sugar for JavaScript. This article uncovers some basic Object Oriented Programming concepts introduced by Type Script, that will wrap the ‘bad parts’ of JavaScript under the carpet so that you can write better code.

imageI suggest you read my post “An Introduction To Type Script” before you read this article.

In this post, Let us explore few features about Classes, Inheritance and Method Overriding in TypeScript.

Classes in Type Script

Classes in TypeScript closely resembles the ECMA proposal according the the language specification. Classes can have private or public members.

Let us start with a very minimal Animal Class in Type Script.  Our Animal class also got a parameterized constructor, that takes name as an input to store it in the 'name' variable of type string, when the instance gets created.

//Our Animal Class
class Animal {

    //Name 
    public name: string;

    //Animal Constructor
    constructor (name: string) {
        this.name = name;
    }

    //A Method, the scope is public by default. ‘this’ points to the class instance
    sayName() {
     
         var span = document.createElement("span");
         span.innerText ="My Name Is" + this.name;
         document.body.appendChild(span);
    }

}

//Let us do something in onload
window.onload = () =>
{
   //Create an instance of Animal
    var a = new Animal("Tommy");
	
   //Invoke the method	
    a.sayName();
}

 

You should see the message from the sayName method, "My name is Tommy".

Parameter property declaration

In the above example, you could find that we are accepting the ‘name’ parameter via a constructor, and then assigning that to a property with name ‘name’. TypeScript has a short cut notation to declare properties with the same name and value as the constructor parameter. For this, you can prefix a constructor parameter with either ‘private’ or ‘public’, so that a property will be declared for you. The below code is functionally equivalent to the above code, see that we are not declaring the property explicitly though it is getting created for us.

//Our Animal Class
class Animal {

    //Animal Constructor. Note that I’m having a 
    //public specifier to the parameter
    constructor (public name: string) {
        //Look ma, I'm not explicitly declaring
        //or assigning to a name
    }

	//A Method, the scope is public by default
    sayName() {
        //The name property is created for you, so you can
        //access this.name
         var span = document.createElement("span");
         span.innerText ="My Name Is" + this.name;
         document.body.appendChild(span);
    }
}

//Let us do something in onload
window.onload = () =>
{
	//Create an instance of Animal
    var a = new Animal("Tommy");
	
	//Invoke the method	
    a.sayName();
}

Run this now, and you should get the same output as the previous one. That was interesting, right?

Inheritance & Overriding

Now, let us quickly explore some inheritance concepts in Type Script. Consider a simple example where you are inheriting a Dog class from the Animal class. You can use the 'extends' key word to extend from a base class. You can also override methods. A derived class will inherit all public members from it’s base class.

//Our Animal Class
class Animal {

	//Animal Constructor
    constructor (public name: string) {
    }

	//A Method, the scope is public by default
    sayName() {
         var span = document.createElement("span");
         span.innerText ="My Name Is" + this.name;
         document.body.appendChild(span);
    }
}


//Let us inherit Dog from Animal
class Dog extends Animal {

    //Override sayName method with some other logic, as usually dogs bark before 
    //saying their name ;)
    sayName() {
         var span = document.createElement("span");
         span.innerText ="Bow Bow, My Name Is" + this.name;
         document.body.appendChild(span);
     }
}

//Let us do something in onload
window.onload = () =>
{
   //Create an instance of Dog and store in an Animal variable
    var a: Animal = new Dog("Tommy");
   //Invoke the method, this will invoke sayName() in Dog class	
    a.sayName();
}

Now, a.sayName() will invoke the sayName(..) method in Dog class.  Now, how will you down cast an instance of Dog from variable a of type ‘Animal’ back to a variable of type Dog?

//Create an instance of Dog and store in an Animal variable
var a: Animal = new Dog("Tommy");

//This will result in an error as what ever you stored in a can be a some other type
//inherited from Animal instead of dog.
var d: Dog = a;

This is how to downcast properly, checkout the <type> syntax
   
//Create an instance of Dog and store in an Animal variable
var a: Animal = new Dog("Tommy");
//Downcasting by ensuring a proper type
var d: Dog = <Dog> a;  

‘super’ Keyword

You can use the super keyword in the constructor of a derived class, to pass the parameters to the base class constructor. Super calls for passing parameters are not allowed outside the constructor in TypeScript, though you can use super keyword to invoke methods of the base class from the derived class. Here is a quick example. See that we are passing the name to the base class constructor from the derived class constructor. Also note that we are using parameter property declaration to declare properties with the same name and value as constructor parameters, as explained above.
//Our Animal Class
class Animal {
	//Animal Constructor
    constructor (public name: string) {
    }
}

class Dog extends Animal {
      //Dog Constructor

      //We are leveraging parameter property declaration
      //to automatically create name and age properties
      constructor (public name: string, public age:number)
      {
        //Note that we are passing name to the 
        //base class constructor to initialize
        super(name);
      }

    sayHello() {
         var span = document.createElement("span");
         span.innerText = "Hello, I'm " + this.name + " with age " + this.age;
         document.body.appendChild(span);
     }
}

//Let us do something in onload
window.onload = () =>
{
  
    //Create an instance of Dog 
    var d: Dog = new Dog("Jim",20);    
    //Make the dog say hello
    d.sayHello();
   
}


Other than using Super for passing constructor parameters to base class, you may also use super for invoking methods in base class - like super.methodName() from methods in your derived class. I intentionally missed covering few other interesting aspects including Modules, Interfaces, Function Overloading, Function types etc - that is for another post.

Stay tuned, and subscribe now.

 
© 2012. All Rights Reserved. Amazedsaint.com