Tabela de Conteúdo
Herança
O que é?
É uma "transferência de informações" entre uma Super Classe e uma Sub Classe, mas vai além de uma "transferência" simples, trata-se de uma ligação, onde se a Super Classe sofre alteração as Sub Classes também sofrerão (o inverso não é verdadeiro).
O que faz?
Como dito em sua definição, logo acima, permite o compartilhamento (transferência) de código entre Classes, evitando a duplicidade de código e facilitando, se bem utilizada, a manutenção.
Sintaxe
Para definirmos que uma Classe herda de outra utilizamos a palavra reservada extends
, informando qual Classe está sendo herdada.
class Animal {}
class Dog extends Animal {}
Peculiaridades na Herança
Atributos
Os atributos continuam com o mesmo encapsulamento mesmo em uma herança, ou seja, se determinado atributo é público podemos acessá-lo normalmente, porém se ele for privado precisaremos nos utilizar de métodos de acesso, assim como faríamos em uma instância da Classe.
Para podermos acessar atributos diretamente a partir de Sub Classes, porém ainda sim privar ele em instâncias, podemos utilizar o encapsulamento protected
, dessa forma temos acesso direto dentro da Sub Classes, porém em Objetos ainda será necessário utilizar os métodos de acesso.
class Animal {
private specie: string; // sem acesso em Sub Classes | sem acesso em instâncias
}
class Animal {
protected specie: string; // com acesso em Sub Classes | sem acesso em instâncias
}
Super
O super
é uma referência ao construtor da Super Classe dentro de uma Sub Classe, sendo necessário declará-lo sempre que a Super Classe tenha um construtor.
Isso é pelo fato de que a Sub Classe possui atributos e métodos em comum com a Super Classe, afinal realizamos uma herança, logo para que a Sub Classe exista é necessário que a Super Classe exista primeiro.
class Animal {
constructor() {}
}
class Dog extends Animal {
constructor() {
super();
}
}
Interfaces
O que são?
Interfaces são "contratos" que definem métodos e atributos públicos a serem declarados por qualquer classe que a implemente.
O que fazem?
Definem uma série de regras a serem seguidas por qualquer classe que implemente determinada Interface, esse conjunto de regras não é funcional, ou seja, definimos apenas que a classe A deverá ter um método X, que tem um retorno do tipo Y, a funcionalidade será implementada posteriormente.
Fazendo um paralelo com Heranças, Interfaces irão definir apenas o "esqueleto" dos métodos e atributos, restringindo seus nomes e tipos, enquanto as Heranças possuem métodos e atributos próprios com valores e funcionamentos previamente definidos.
Sintaxe
A sintaxe para definirmos uma Interface é muito simples, tudo que precisamos fazer é utilizar a palavra reservada interface
, seguida do nome que desejamos dar a ela, após isso abrimos chaves, definindo os nomes e tipos dos atributos e métodos.
interface IDog { // opcionalmente podemos colocar um "I" maiúsculo a frente de toda a interface
name: string;
age: number;
bark(): void;
}
Composição
O que é?
É uma maneira de termos a disposição métodos e atributos de classes que não fazem sentido serem herdadas por outra determinada classe, por exemplo, imagine que temos uma API de xadrez, onde existem duas classes uma representa o DB e a outra representa o tabuleiro, sendo que queremos salvar o tabuleiro em nosso DB.
Não faz sentido a classe Tabuleiro herdar a classe BancoDeDados, pois um tabuleiro não é um tipo de DB, porém ainda sim precisamos das funcionalidades dessa classe para salvar nosso tabuleiro, nesse ponto entra a Composição.
Sintaxe
Para realizarmos a Composição entre classes, tudo que precisamos fazer é indicar que uma classe recebe a instância de outra através de seu construtor, ou, retomando o exemplo anterior, a classe Tabuleiro irá receber a instância da classe BancoDeDados através dos parâmetros.
interface IBancoDeDados {
save(data: any): void;
}
class BancoDeDados implements IBancoDeDados {
save(data) {
/* lógica para salvar no DB */
}
}
interface ITabuleiro {
boardData: string;
save(): void;
}
class Tabuleiro implements ITabuleiro {
constructor(
public boardData: string,
private bancoDeDados: IBancoDeDados // é uma boa prática "tipar" outra classe a partir de sua Interface
) {}
save() {
this.bancoDeDados.save(this.boardData);
}
}
const dataBase = new BancoDeDados();
const board = new Tabuleiro(['A1', 'A2', 'B1', 'B2'], dataBase);
board.save();
Top comments (0)