com TypeScript

Orientação a Objetos

O que é o TypeScript?

Desenvolvido pela Microsoft em 2012, com o objetivo de adicionar recursos e ferramentas que não estão presentes nativamente na linguagem JavaScript, como tipagem estática e orientação a objetos.

Não é considerado uma nova linguagem de programação, mas sim um superconjunto de JavaScript, pois o código escrito em TypeScript é "transformado" em JavaScript "puro" antes de ser executado.

A principal caraterística do TypeScript é sua tipagem forte, razão pela qual leva no seu nome type. Além disso existe outra característica importante, a Orientação a Objetos.

Node.js

É um ambiente de execução do código JavaScript do lado servidor (server side), sem a necessidade do navegador.

github.com/woodyalan/poo_typescript

cd poo_typescript/
npm install
npm run start:dev
let textoQualquer: string = "Olá mundo";
// erro devido a tipagem
textoQualquer = 2;

src/app.ts

Orientação a Objetos

Programação Orientada a Objetos (POO) é uma forma de organizar código utilizando o conceito de objetos, geralmente representando algo do mundo real. Esses objetos contém informações e ações, que interagem entre si durante a execução do programa.

A reutilização de código, leitura, manutenção e facilidade na criação de bibliotecas são as principais vantagens da POO.

Objeto do tipo celular
   Modelo: iPhone 13
   Câmera: 12mp
   Memória Interna: 128gb
   Tipo: Smartphone
   Marca: Apple
Objeto do tipo celular
   Modelo: Redmi Note 12
   Câmera: 200mp
   Memória Interna: 256gb
   Tipo: Smartphone
   Marca: Xiaomi

As características (modelo, marca, etc.) de um objeto chamaremos de atributos e as ações (ligar, fotografar, etc.) de métodos. O conjunto de objeto + atributos + métodos representa um dos conceitos mais importantes da POO, a Abstração.

Classes

Classes são como moldes para objetos, onde são descriminados os atributos e métodos que nossos objetos devem possuir. Os objetos criados a partir das classes são instâncias dessas classes, sendo objetos diferentes que compartilham o mesmo molde.

export class Celular {
  marca: string;
  modelo: string;
  capacidadeMemoriaInterna: number;
  qualidadeCamera: number;
  tipo: string;
}

src/models/Celular.ts

export class Celular {
  // ...
  fazerLigacao() {
    console.log("Fazendo ligação...");
  }

  receberLigacao() {
    console.log("Recebendo ligação...");
  }

  fotografar() {
    console.log("Fotografando...");
  }
}

src/models/Celular.ts

import { Celular } from "./models/Celular";

let iphone13 = new Celular();
iphone13.fazerLigacao();

src/app.ts

Construtores

Um construtor é um método executado sempre que um novo objeto é criado por meio do operador new. Toda classe possui um construtor definido, porém podemos criar nossos próprios construtores, personalizando a criação de um objeto.

export class Celular {
  // ...
  constructor(
    marca: string,
    modelo: string,
    capacidadeMemoriaInterna: number,
    qualidadeCamera: number,
    tipo: string
  ) {
    this.marca = marca;
    this.modelo = modelo;
    this.capacidadeMemoriaInterna = capacidadeMemoriaInterna;
    this.qualidadeCamera = qualidadeCamera;
    this.tipo = tipo;
    this.nivelBateria = 100;
  }
}

src/models/Celular.ts

import { Celular } from "./models/Celular";

let iphone13 = new Celular(
  "Apple",
  "iPhone 13",
  128,
  12,
  "Smartphone"
);
iphone13.fazerLigacao();

src/app.ts

Encapsulamento

Encapsulamento é uma das principais técnicas que define a programação orientada a objetos. Ela é responsável por adicionar segurança a uma aplicação escondendo atributos e métodos, como uma caixa preta.

Com encapsulamento é possível definir atributos e métodos privados. Com isso os atributos privados terão métodos especiais para ler e atualizar seus valores, chamados de getters e setters. Com isso evitamos o acesso direto a uma propriedade ou método do objeto. 

export class Celular {
  private _modelo: string;
  public readonly _capacidadeCamera: number;
  
  public set modelo(modelo: string) {
    this._modelo = modelo;
  }

  public get modelo(): string {
    return this._modelo;
  }
}

src/models/Celular.ts

Herança

É um princípio da orientação a objetos, que possibilita que as classes compartilhem seus atributos e métodos. É um tipo de relacionamento entre classes que significa que uma classe é outra.

export default Ave extends Animal {
  private _aquatico: boolean;
  
  constructor(
    nome: string, 
    peso: number, 
    cor: string, 
    raca: string, 
    aquatico: boolean
  ) {
    super(nome, peso, cor, raca);
    this._aquatico = aquatico;
  }
  
  public voar(): void {
    console.log(`${this.nome} voando...`);
  }
}

src/models/Ave.ts

let pombo = new Ave(...);

src/app.ts

Polimorfismo

Enfim, o último princípio da POO. Permite que as classes, além de herdar características e propriedades, sejam capazes de invocar os métodos comportam-se de maneira diferente para cada uma das classes derivadas.

Classes Abstratas

São classes que não podem ser instanciadas, apenas herdadas, possibilitando ainda a criação de métodos abstratos, item exclusivo em Classes Abstratas e devem ser implementados em qualquer Sub Classe de uma Super Classe Abstrata.

Nas classes podemos definir outros métodos e atributos que não são abstratos, podendo receber funcionalidades e valores.

export abstract class Animal {
  //...

  abstract locomover(metros: number): void;
}

src/class/Animal.ts

export class Ave extends Animal {
  aquatico: boolean;

  //...

  public botarOvo() {
    console.log(this.nome, "Botando ovo...");
  }

  emitirSom(som: string): void {
    throw new Error("Method not implemented.");
  }

  locomover(passos: number): void {
    throw new Error("Method not implemented.");
  }
}

src/class/Ave.ts