Abstração

Abstração é um dos princípios fundamentais da programação orientada a objetos. Ela envolve a criação de classes que representam objetos do mundo real com propriedades e comportamentos específicos, enquanto oculta os detalhes internos complexos e mostra apenas as informações necessárias para o usuário. A abstração permite que você modele objetos complexos em termos de suas características essenciais, ignorando os detalhes não essenciais.

Em JavaScript, a abstração pode ser alcançada por meio do uso de classes e interfaces (embora JavaScript não tenha uma implementação formal de interfaces como outras linguagens de programação orientada a objetos). Vou mostrar um exemplo simples usando classes:

class Forma {
    constructor(tipo) {
        this.tipo = tipo;
    }

    calcularArea() {
        throw new Error("Método calcularArea() deve ser implementado na subclasse.");
    }
}

class Retangulo extends Forma {
    constructor(largura, altura) {
        super("Retângulo");
        this.largura = largura;
        this.altura = altura;
    }

    calcularArea() {
        return this.largura * this.altura;
    }
}

class Circulo extends Forma {
    constructor(raio) {
        super("Círculo");
        this.raio = raio;
    }

    calcularArea() {
        return Math.PI * this.raio ** 2;
    }
}

let retangulo = new Retangulo(5, 10);
let circulo = new Circulo(3);

console.log(retangulo.calcularArea()); // Saída: 50
console.log(circulo.calcularArea()); // Saída: ~28.27

Neste exemplo, Forma é uma classe abstrata que define uma propriedade tipo e um método calcularArea(). A função calcularArea() é declarada, mas não é implementada na classe base Forma. Isso obriga as subclasses (Retangulo e Circulo) a fornecerem sua própria implementação do método calcularArea(). Esta é uma forma de aplicar abstração: a classe base fornece uma estrutura geral, enquanto as subclasses implementam detalhes específicos.

O uso da palavra-chave throw new Error(...) no método calcularArea() da classe Forma indica que qualquer objeto da classe Forma não pode calcular a área diretamente, e uma subclasse deve fornecer uma implementação para esse método.

Essa abordagem permite que você use a classe abstrata Forma como um tipo genérico, enquanto força as subclasses a implementarem os detalhes específicos do método calcularArea(). Isso é um exemplo de abstração, pois oculta os detalhes de implementação dos métodos, fornecendo apenas uma interface clara para os usuários da classe.