Classes e membros abstratos
Definição
As subclasses possuem o mesmo tipo da superclasse.
As classes e membros abstratos (abstract
) formam um “contrato” com as subclasses, ou seja, as classe que herdam dessa superclasse devem implementar os membros abstratos dela.
Classe abstrata não pode ser instanciada diretamente, ou seja, só é possível instanciar as subclasses (classes concretas) dela:
-
Forma incorreta:
abstract class Character { // ... } const character = new Character(...); // Erro de compilação
-
Forma correta:
abstract class Character { // ... } class Warrior extends Character { // ... } class Monster extends Character { // ... } const warrior = new Warrior(...); const monster = new Monster(...);
Método abstrato não pode ter implementação (corpo) na superclasse (abstrata):
-
Forma incorreta:
abstract class Character { abstract attackPhrase(): void { // Corpo -> erro de compilação } }
-
Forma correta:
abstract class Character { abstract attackPhrase(): void; }
OBS: o tipo de retorno deve ser definido explicitamente em métodos abstratos
Exemplo
abstract class Character {
protected abstract emoji: string;
constructor(
protected name: string,
protected damage: number,
protected life: number
) {}
removeLife(damage: number): void {
this.life -= damage;
console.log(`${this.name} sofreu um dano de ${damage} pontos de vida...`);
}
abstract attackPhrase(): void;
attack(target: Character): void {
this.attackPhrase();
target.removeLife(this.damage);
}
}
class Warrior extends Character {
protected emoji = "\u{1F9DD}";
attackPhrase(): void {
console.log(`${this.emoji} Atacarrrr!`);
}
}
class Monster extends Character {
protected emoji = "\u{1F9DF}";
attackPhrase(): void {
console.log(`${this.emoji} Krr Krr!`);
}
}
const warrior = new Warrior("Guerreiro", 12, 100);
const monster = new Monster("Monstro", 9, 50);
warrior.attack(monster);
monster.attack(warrior);
/*
🧝 Atacarrrr!
Monstro sofreu um dano de 12 pontos de vida...
🧟 Krr Krr!
Guerreiro sofreu um dano de 9 pontos de vida...
*/