TypeScript - Classes
TypeScript é JavaScript orientado a objetos. TypeScript oferece suporte a recursos de programação orientada a objetos, como classes, interfaces, etc. Uma classe em termos de OOP é um projeto para a criação de objetos. Uma classe encapsula dados para o objeto. O Typescript fornece suporte integrado para este conceito chamado classe. JavaScript ES5 ou anterior não suportava classes. O typescript obtém esse recurso do ES6.
Criação de classes
Use a palavra-chave class para declarar uma classe em TypeScript. A sintaxe para o mesmo é fornecida abaixo -
Sintaxe
class class_name {
//class scope
}
A palavra-chave class é seguida pelo nome da classe. As regras para identificadores devem ser consideradas ao nomear uma classe.
Uma definição de classe pode incluir o seguinte -
Fields- Um campo é qualquer variável declarada em uma classe. Os campos representam dados pertencentes a objetos
Constructors - Responsável por alocar memória para os objetos da aula
Functions- Funções representam ações que um objeto pode realizar. Eles também são às vezes chamados de métodos
Esses componentes juntos são chamados de membros de dados da classe.
Considere uma classe Person em texto datilografado.
class Person {
}
Na compilação, ele irá gerar o seguinte código JavaScript.
//Generated by typescript 1.8.10
var Person = (function () {
function Person() {
}
return Person;
}());
Exemplo: Declarando uma classe
class Car {
//field
engine:string;
//constructor
constructor(engine:string) {
this.engine = engine
}
//function
disp():void {
console.log("Engine is : "+this.engine)
}
}
O exemplo declara uma classe Car. A classe possui um campo denominado engine. ovarpalavra-chave não é usada ao declarar um campo. O exemplo acima declara um construtor para a classe.
Um construtor é uma função especial da classe responsável por inicializar as variáveis da classe. TypeScript define um construtor usando a palavra-chave constructor. Um construtor é uma função e, portanto, pode ser parametrizado.
o thispalavra-chave refere-se à instância atual da classe. Aqui, o nome do parâmetro e o nome do campo da classe são os mesmos. Portanto, para evitar ambigüidade, o campo da classe é prefixado com othis palavra-chave.
disp () é uma definição de função simples. Observe que a palavra-chave da função não é usada aqui.
Na compilação, ele irá gerar o seguinte 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;
}());
Criação de objetos Instance
Para criar uma instância da classe, use o newpalavra-chave seguida pelo nome da classe. A sintaxe para o mesmo é fornecida abaixo -
Sintaxe
var object_name = new class_name([ arguments ])
o new palavra-chave é responsável pela instanciação.
O lado direito da expressão invoca o construtor. O construtor deve receber valores se for parametrizado.
Exemplo: instanciando uma classe
var obj = new Car("Engine 1")
Acessando atributos e funções
Os atributos e funções de uma classe podem ser acessados por meio do objeto. Use o ' . 'notação de ponto (chamada de ponto) para acessar os membros de dados de uma classe.
//accessing an attribute
obj.field_name
//accessing a function
obj.function_name()
Exemplo: juntando-os
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()
Na compilação, ele irá gerar o seguinte 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();
A saída do código acima é a seguinte -
Reading attribute value Engine as : XXSY1
Function displays Engine is : XXSY1
Herança de classe
TypeScript oferece suporte ao conceito de herança. Herança é a capacidade de um programa de criar novas classes a partir de uma classe existente. A classe que é estendida para criar classes mais novas é chamada de classe pai / superclasse. As classes recém-criadas são chamadas de classes filhas / subclasses.
Uma classe herda de outra classe usando a palavra-chave 'extends'. As classes filhas herdam todas as propriedades e métodos, exceto membros privados e construtores da classe pai.
Sintaxe
class child_class_name extends parent_class_name
No entanto, o TypeScript não oferece suporte a herança múltipla.
Exemplo: herança de classe
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()
Na compilação, ele irá gerar o seguinte 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();
A saída do código acima é a seguinte -
Area of the Circle: 223
O exemplo acima declara uma classe Shape. A aula é estendida pela classe Circle. Visto que existe uma relação de herança entre as classes, a classe filha, isto é, a classe Car, obtém um acesso implícito ao seu atributo de classe pai, isto é, área.
A herança pode ser classificada como -
Single - Cada classe pode estender-se, no máximo, de uma classe pai
Multiple- Uma classe pode herdar de várias classes. TypeScript não oferece suporte a herança múltipla.
Multi-level - O exemplo a seguir mostra como funciona a herança de vários níveis.
Exemplo
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)
A classe Leaf deriva os atributos das classes Root e Child em virtude da herança de vários níveis.
Na compilação, ele irá gerar o seguinte 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);
Seu resultado é o seguinte -
Resultado
hello
TypeScript ─ herança de classe e substituição de método
Substituição de Método é um mecanismo pelo qual a classe filha redefine o método da superclasse. O exemplo a seguir ilustra o mesmo -
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()
A palavra-chave super é usada para se referir ao pai imediato de uma classe. A palavra-chave pode ser usada para se referir à versão da superclasse de uma variável, propriedade ou método. A linha 13 invoca a versão de superclasse da função doWork ().
Na compilação, ele irá gerar o seguinte 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();
A saída do código acima é a seguinte -
doPrint() from Parent called…
doPrint() is printing a string…
A palavra-chave estática
A palavra-chave estática pode ser aplicada aos membros de dados de uma classe. Uma variável estática retém seus valores até que o programa termine a execução. Membros estáticos são referenciados pelo nome da classe.
Exemplo
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
Na compilação, ele irá gerar o seguinte 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
A saída do código acima é a seguinte -
The value of num is 12
O operador instanceof
o instanceof operador retorna verdadeiro se o objeto pertencer ao tipo especificado.
Exemplo
class Person{ }
var obj = new Person()
var isPerson = obj instanceof Person;
console.log(" obj is an instance of Person " + isPerson);
Na compilação, ele irá gerar o seguinte 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);
A saída do código acima é a seguinte -
obj is an instance of Person True
Ocultação de dados
Uma classe pode controlar a visibilidade de seus membros de dados para membros de outras classes. Este recurso é denominado Ocultação de Dados ou Encapsulamento.
Orientação a Objetos usa o conceito de modificadores de acesso ou especificadores de acesso para implementar o conceito de Encapsulamento. Os especificadores / modificadores de acesso definem a visibilidade dos membros de dados de uma classe fora de sua classe de definição.
Os modificadores de acesso suportados pelo TypeScript são -
S.No. | Especificador de acesso e descrição |
---|---|
1 | public Um membro de dados públicos tem acessibilidade universal. Membros de dados em uma classe são públicos por padrão. |
2 | private Membros de dados privados são acessíveis apenas dentro da classe que define esses membros. Se um membro da classe externa tentar acessar um membro privado, o compilador gerará um erro. |
3 - | protected Um membro de dados protegido pode ser acessado pelos membros da mesma classe do primeiro e também pelos membros das classes filhas. |
Exemplo
Vamos agora dar um exemplo para ver como funciona a ocultação de dados -
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
A classe tem dois atributos de string, str1 e str2, que são membros públicos e privados, respectivamente. A classe é instanciada. O exemplo retorna um erro de tempo de compilação, pois o atributo privado str2 é acessado fora da classe que o declara.
Classes e Interfaces
As classes também podem 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 )
A classe AgriLoan implementa a interface Loan. Portanto, agora é obrigatório para a classe incluir a propriedadeinterest como seu membro.
Na compilação, ele irá gerar o seguinte 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);
A saída do código acima é a seguinte -
Interest is : 10 Rebate is : 1