Herança

A herança é um conceito fundamental na programação orientada a objetos que permite criar uma nova classe (ou objeto) com base em uma classe existente (ou objeto). Em JavaScript, a herança é baseada em protótipos. Cada objeto em JavaScript tem um protótipo associado, que é um objeto de onde ele herda propriedades e métodos.

Aqui está como você pode implementar herança em JavaScript:

Herança de Protótipos:

// Classe pai (ou superclasse)
function Animal(nome) {
    this.nome = nome;
}

// Adicionando um método ao protótipo de Animal
Animal.prototype.fazerBarulho = function() {
    console.log("Barulho genérico de animal");
};

// Classe filha (ou subclasse) que herda de Animal
function Cachorro(nome, raca) {
    Animal.call(this, nome); // Chama o construtor da classe pai para inicializar propriedades
    this.raca = raca;
}

// Herda métodos e propriedades de Animal
Cachorro.prototype = Object.create(Animal.prototype);

// Adicionando um método específico para Cachorro
Cachorro.prototype.fazerBarulho = function() {
    console.log("Latido de cachorro");
};

var meuCachorro = new Cachorro("Max", "Labrador");
meuCachorro.fazerBarulho(); // Saída: "Latido de cachorro"

Neste exemplo, Cachorro herda de Animal. O método Object.create(Animal.prototype) cria um novo objeto que tem o protótipo de Animal.prototype, assim Cachorro.prototype herda os métodos de Animal. O método fazerBarulho é sobrescrito na classe Cachorro, substituindo a implementação na classe Animal.

Herança de Classes (ES6+):

A partir do ECMAScript 6 (ES6), o JavaScript introduziu uma sintaxe mais amigável para definir classes e herança:

class Animal {
    constructor(nome) {
        this.nome = nome;
    }

    fazerBarulho() {
        console.log("Barulho genérico de animal");
    }
}

class Cachorro extends Animal {
    constructor(nome, raca) {
        super(nome); // Chama o construtor da classe pai para inicializar propriedades
        this.raca = raca;
    }

    fazerBarulho() {
        console.log("Latido de cachorro");
    }
}

let meuCachorro = new Cachorro("Max", "Labrador");
meuCachorro.fazerBarulho(); // Saída: "Latido de cachorro"

Neste exemplo, class é usada para definir tanto Animal quanto Cachorro. A palavra-chave extends é usada para estabelecer a herança, e super() é usado para chamar o construtor da classe pai.

Ambas as abordagens, usando herança de protótipos ou classes, permitem criar uma hierarquia de classes em JavaScript, onde as classes filhas herdam propriedades e métodos das classes pai.