TypeScript - Clases

TypeScript es JavaScript orientado a objetos. TypeScript admite funciones de programación orientadas a objetos como clases, interfaces, etc. Una clase en términos de POO es un modelo para crear objetos. Una clase encapsula los datos del objeto. TypeScript brinda soporte integrado para este concepto llamado clase. JavaScript ES5 o versiones anteriores no admitían clases. Typecript obtiene esta función de ES6.

Creando clases

Utilice la palabra clave class para declarar una clase en TypeScript. La sintaxis para el mismo se da a continuación:

Sintaxis

class class_name { 
   //class scope 
}

La palabra clave class va seguida del nombre de la clase. Las reglas para los identificadores deben tenerse en cuenta al nombrar una clase.

Una definición de clase puede incluir lo siguiente:

  • Fields- Un campo es cualquier variable declarada en una clase. Los campos representan datos pertenecientes a objetos

  • Constructors - Responsable de asignar memoria para los objetos de la clase.

  • Functions- Las funciones representan acciones que puede realizar un objeto. A veces también se les conoce como métodos

Estos componentes juntos se denominan miembros de datos de la clase.

Considere una persona de la clase en texto mecanografiado.

class Person {
}

Al compilar, generará el siguiente código JavaScript.

//Generated by typescript 1.8.10
var Person = (function () {
   function Person() {
   }
   return Person;
}());

Ejemplo: declarar una clase

class Car { 
   //field 
   engine:string; 
 
   //constructor 
   constructor(engine:string) { 
      this.engine = engine 
   }  

   //function 
   disp():void { 
      console.log("Engine is  :   "+this.engine) 
   } 
}

El ejemplo declara una clase Car. La clase tiene un campo llamado motor. losvarLa palabra clave no se utiliza al declarar un campo. El ejemplo anterior declara un constructor para la clase.

Un constructor es una función especial de la clase que se encarga de inicializar las variables de la clase. TypeScript define un constructor usando la palabra clave constructor. Un constructor es una función y, por tanto, se puede parametrizar.

los thispalabra clave se refiere a la instancia actual de la clase. Aquí, el nombre del parámetro y el nombre del campo de la clase son los mismos. Por lo tanto, para evitar la ambigüedad, el campo de la clase tiene el prefijothis palabra clave.

disp () es una definición de función simple. Tenga en cuenta que aquí no se utiliza la palabra clave de función.

Al compilar, generará el siguiente código JavaScript.

//Generated by typescript 1.8.10
var Car = (function () {
   //constructor
   function Car(engine) {
      this.engine = engine;
   }
	
   //function
   Car.prototype.disp = function () {
      console.log("Engine is  :   " + this.engine);
   };
   return Car;
}());

Crear objetos de instancia

Para crear una instancia de la clase, use el newpalabra clave seguida del nombre de la clase. La sintaxis para el mismo se da a continuación:

Sintaxis

var object_name = new class_name([ arguments ])
  • los new La palabra clave es responsable de la creación de instancias.

  • El lado derecho de la expresión invoca al constructor. Se deben pasar valores al constructor si está parametrizado.

Ejemplo: instanciar una clase

var obj = new Car("Engine 1")

Acceder a atributos y funciones

Se puede acceder a los atributos y funciones de una clase a través del objeto. Utilizar el ' . 'notación de puntos (llamada punto) para acceder a los miembros de datos de una clase.

//accessing an attribute 
obj.field_name 

//accessing a function 
obj.function_name()

Ejemplo: ponerlos juntos

class Car { 
   //field 
   engine:string; 
   
   //constructor 
   constructor(engine:string) { 
      this.engine = engine 
   }  
   
   //function 
   disp():void { 
      console.log("Function displays Engine is  :   "+this.engine) 
   } 
} 

//create an object 
var obj = new Car("XXSY1")

//access the field 
console.log("Reading attribute value Engine as :  "+obj.engine)  

//access the function
obj.disp()

Al compilar, generará el siguiente código JavaScript.

//Generated by typescript 1.8.10
var Car = (function () {
   //constructor
   function Car(engine) {
      this.engine = engine;
   }
	
   //function
   Car.prototype.disp = function () {
      console.log("Function displays Engine is  :   " + this.engine);
   };
   return Car;
}());

//create an object
var obj = new Car("XXSY1");

//access the field
console.log("Reading attribute value Engine as :  " + obj.engine);

//access the function
obj.disp();

La salida del código anterior es la siguiente:

Reading attribute value Engine as :  XXSY1 
Function displays Engine is  :   XXSY1

Herencia de clase

TypeScript admite el concepto de herencia. La herencia es la capacidad de un programa para crear nuevas clases a partir de una clase existente. La clase que se amplía para crear clases más nuevas se denomina clase padre / superclase. Las clases recién creadas se denominan clases secundarias / subclases.

Una clase hereda de otra clase usando la palabra clave 'extiende'. Las clases secundarias heredan todas las propiedades y métodos excepto los miembros privados y los constructores de la clase principal.

Sintaxis

class child_class_name extends parent_class_name

Sin embargo, TypeScript no admite la herencia múltiple.

Ejemplo: herencia de clase

class Shape { 
   Area:number 
   
   constructor(a:number) { 
      this.Area = a 
   } 
} 

class Circle extends Shape { 
   disp():void { 
      console.log("Area of the circle:  "+this.Area) 
   } 
}
  
var obj = new Circle(223); 
obj.disp()

Al compilar, generará el siguiente código JavaScript.

//Generated by typescript 1.8.10
var __extends = (this && this.__extends) || function (d, b) {
   for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
   function __() { this.constructor = d; }
   d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var Shape = (function () {
   function Shape(a) {
      this.Area = a;
   }
   return Shape;
}());

var Circle = (function (_super) {
   __extends(Circle, _super);
   function Circle() {
      _super.apply(this, arguments);
   }
	
   Circle.prototype.disp = function () { 
      console.log("Area of the circle:  " + this.Area); 
   };
   return Circle;
}(Shape));

var obj = new Circle(223);
obj.disp();

La salida del código anterior es la siguiente:

Area of the Circle: 223

El ejemplo anterior declara una clase Shape. La clase se amplía con la clase Circle. Dado que existe una relación de herencia entre las clases, la clase secundaria, es decir, la clase Coche, obtiene un acceso implícito a su atributo de clase principal, es decir, el área.

La herencia se puede clasificar como:

  • Single - Cada clase puede extenderse como máximo desde una clase principal

  • Multiple- Una clase puede heredar de varias clases. TypeScript no admite herencia múltiple.

  • Multi-level - El siguiente ejemplo muestra cómo funciona la herencia multinivel.

Ejemplo

class Root { 
   str:string; 
} 

class Child extends Root {} 
class Leaf extends Child {} //indirectly inherits from Root by virtue of inheritance  

var obj = new Leaf(); 
obj.str ="hello" 
console.log(obj.str)

La clase Leaf deriva los atributos de las clases Root y Child en virtud de la herencia de varios niveles.

Al compilar, generará el siguiente código JavaScript.

//Generated by typescript 1.8.10
var __extends = (this && this.__extends) || function (d, b) {
   for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
   function __() { this.constructor = d; }
   d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};

var Root = (function () {
   function Root() {
   }
   return Root;
}());

var Child = (function (_super) {
   __extends(Child, _super);
   function Child() {
      _super.apply(this, arguments);
   }
   return Child;
}(Root));

var Leaf = (function (_super) {
   __extends(Leaf, _super);
   function Leaf() {
      _super.apply(this, arguments);
   }
   return Leaf;
}(Child));

var obj = new Leaf();
obj.str = "hello";
console.log(obj.str);

Su salida es la siguiente:

Salida

hello

TypeScript: herencia de clases y anulación de métodos

La anulación de método es un mecanismo mediante el cual la clase secundaria redefine el método de la superclase. El siguiente ejemplo ilustra lo mismo:

class PrinterClass { 
   doPrint():void {
      console.log("doPrint() from Parent called…") 
   } 
} 

class StringPrinter extends PrinterClass { 
   doPrint():void { 
      super.doPrint() 
      console.log("doPrint() is printing a string…")
   } 
} 

var obj = new StringPrinter() 
obj.doPrint()

La palabra clave super se utiliza para referirse al padre inmediato de una clase. La palabra clave se puede utilizar para hacer referencia a la versión de superclase de una variable, propiedad o método. La línea 13 invoca la versión de superclase de la función doWork ().

Al compilar, generará el siguiente código JavaScript.

//Generated by typescript 1.8.10
var __extends = (this && this.__extends) || function (d, b) {
   for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
   function __() { this.constructor = d; }
   d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};

var PrinterClass = (function () {
   function PrinterClass() {
   }
   PrinterClass.prototype.doPrint = function () { 
      console.log("doPrint() from Parent called…"); 
   };
   return PrinterClass;
}());

var StringPrinter = (function (_super) {
   __extends(StringPrinter, _super);
	
   function StringPrinter() {
      _super.apply(this, arguments);
   }
	
   StringPrinter.prototype.doPrint = function () {
      _super.prototype.doPrint.call(this);
      console.log("doPrint() is printing a string…");
   };
	
   return StringPrinter;
}(PrinterClass));

var obj = new StringPrinter();
obj.doPrint();

La salida del código anterior es la siguiente:

doPrint() from Parent called… 
doPrint() is printing a string…

La palabra clave estática

La palabra clave estática se puede aplicar a los miembros de datos de una clase. Una variable estática conserva sus valores hasta que el programa finaliza la ejecución. Los miembros estáticos son referenciados por el nombre de la clase.

Ejemplo

class StaticMem {  
   static num:number; 
   
   static disp():void { 
      console.log("The value of num is"+ StaticMem.num) 
   } 
} 

StaticMem.num = 12     // initialize the static variable 
StaticMem.disp()      // invoke the static method

Al compilar, generará el siguiente código JavaScript.

//Generated by typescript 1.8.10
var StaticMem = (function () {
   function StaticMem() {
   }
	
   StaticMem.disp = function () {
      console.log("The value of num is" + StaticMem.num);
   };
	
   return StaticMem;
}());

StaticMem.num = 12;     // initialize the static variable
StaticMem.disp();      // invoke the static method

La salida del código anterior es la siguiente:

The value of num is 12

El operador instanceof

los instanceof El operador devuelve verdadero si el objeto pertenece al tipo especificado.

Ejemplo

class Person{ } 
var obj = new Person() 
var isPerson = obj instanceof Person; 
console.log(" obj is an instance of Person " + isPerson);

Al compilar, generará el siguiente código JavaScript.

//Generated by typescript 1.8.10
var Person = (function () {
   function Person() {
   }
   return Person;
}());

var obj = new Person();
var isPerson = obj instanceof Person;
console.log(" obj is an instance of Person " + isPerson);

La salida del código anterior es la siguiente:

obj is an instance of Person True

Ocultar datos

Una clase puede controlar la visibilidad de sus miembros de datos para los miembros de otras clases. Esta capacidad se denomina ocultación o encapsulación de datos.

Orientación a objetos utiliza el concepto de modificadores de acceso o especificadores de acceso para implementar el concepto de Encapsulación. Los especificadores / modificadores de acceso definen la visibilidad de los miembros de datos de una clase fuera de su clase definitoria.

Los modificadores de acceso admitidos por TypeScript son:

S.No. Especificador de acceso y descripción
1.

public

Un miembro de datos públicos tiene accesibilidad universal. Los miembros de datos de una clase son públicos de forma predeterminada.

2.

private

Los miembros de datos privados son accesibles solo dentro de la clase que define a estos miembros. Si un miembro de la clase externa intenta acceder a un miembro privado, el compilador arroja un error.

3.

protected

Un miembro de datos protegidos es accesible por los miembros dentro de la misma clase que el anterior y también por los miembros de las clases secundarias.

Ejemplo

Tomemos ahora un ejemplo para ver cómo funciona la ocultación de datos:

class Encapsulate { 
   str:string = "hello" 
   private str2:string = "world" 
}
 
var obj = new Encapsulate() 
console.log(obj.str)     //accessible 
console.log(obj.str2)   //compilation Error as str2 is private

La clase tiene dos atributos de cadena, str1 y str2, que son miembros públicos y privados respectivamente. Se crea una instancia de la clase. El ejemplo devuelve un error de tiempo de compilación, ya que se accede al atributo privado str2 fuera de la clase que lo declara.

Clases e interfaces

Las clases también pueden implementar interfaces.

interface ILoan { 
   interest:number 
} 

class AgriLoan implements ILoan { 
   interest:number 
   rebate:number 
   
   constructor(interest:number,rebate:number) { 
      this.interest = interest 
      this.rebate = rebate 
   } 
} 

var obj = new AgriLoan(10,1) 
console.log("Interest is : "+obj.interest+" Rebate is : "+obj.rebate )

La clase AgriLoan implementa la interfaz Loan. Por lo tanto, ahora es obligatorio para la clase incluir la propiedadinterest como su miembro.

Al compilar, generará el siguiente código JavaScript.

//Generated by typescript 1.8.10
var AgriLoan = (function () {
   function AgriLoan(interest, rebate) {
      this.interest = interest;
      this.rebate = rebate;
   }
   return AgriLoan;
}());

var obj = new AgriLoan(10, 1);
console.log("Interest is : " + obj.interest + " Rebate is : " + obj.rebate);

La salida del código anterior es la siguiente:

Interest is : 10 Rebate is : 1