Resumo : neste tutorial, você aprenderá como implementar a herança JavaScript usando extends
e super
no ES6.
Implementando herança JavaScript usando extends
esuper
Antes do ES6, a implementação de uma herança adequada exigia várias etapas. Uma das estratégias mais comumente utilizadas é a herança prototípica .
O seguinte ilustra como o Bird
herda propriedades do Animal
uso da técnica de herança prototípica:
function Animal(legs) {
this.legs = legs;
}
Animal.prototype.walk = function() {
console.log('walking on ' + this.legs + ' legs');
}
function Bird(legs) {
Animal.call(this, legs);
}
Bird.prototype = Object.create(Animal.prototype);
Bird.prototype.constructor = Animal;
Bird.prototype.fly = function() {
console.log('flying');
}
var pigeon = new Bird(2);
pigeon.walk(); // walking on 2 legs
pigeon.fly(); // flying
Linguagem de código: JavaScript ( javascript )
ES6 simplificou essas etapas usando as palavras-chave extends
e super
.
O exemplo a seguir define as classes Animal
e Bird
e estabelece a herança por meio das palavras-chave extends
and super
.
class Animal {
constructor(legs) {
this.legs = legs;
}
walk() {
console.log('walking on ' + this.legs + ' legs');
}
}
class Bird extends Animal {
constructor(legs) {
super(legs);
}
fly() {
console.log('flying');
}
}
let bird = new Bird(2);
bird.walk();
bird.fly();
Linguagem de código: JavaScript ( javascript )
Como funciona.
Primeiro, use a extends
palavra-chave para fazer com que a Bird
classe herde da Animal
classe:
class Bird extends Animal {
// ...
}
Linguagem de código: JavaScript ( javascript )
A Animal
classe é chamada de classe base ou classe pai , enquanto a Bird
classe é conhecida como classe derivada ou classe filha . Ao fazer isso, a Bird
classe herda todos os métodos e propriedades da Animal
classe.
Segundo, no Bird
construtor do ‘, chame super()
para invocar o Animal
construtor do’ com o legs
argumento.
JavaScript exige que a classe filha chame super()
se tiver um construtor. Como você pode ver na Bird
classe, super(legs)
é equivalente à seguinte instrução em ES5:
Animal.call(this, legs);
Linguagem de código: JavaScript ( javascript )
Se a Bird
classe não tiver um construtor, você não precisa fazer mais nada:
class Bird extends Animal {
fly() {
console.log('flying');
}
}
Linguagem de código: JavaScript ( javascript )
É equivalente à seguinte classe:
class Bird extends Animal {
constructor(...args) {
super(...args);
}
fly() {
console.log('flying');
}
}
Linguagem de código: JavaScript ( javascript )
Porém, a classe filha possui um construtor, ela precisa chamar super()
. Por exemplo, o código a seguir resulta em um erro:
class Bird extends Animal {
constructor(legs) {
}
fly() {
console.log('flying');
}
}
Linguagem de código: JavaScript ( javascript )
Erro:
ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor
Linguagem de código: JavaScript ( javascript )
Como o super()
inicializa o this
objeto, você precisa chamar o super()
antes de acessar o this
objeto. Tentar acessar this
antes de ligar super()
também resulta em erro.
Por exemplo, se quiser inicializar a color
propriedade da Bird
classe, você pode fazer o seguinte:
class Bird extends Animal {
constructor(legs, color) {
super(legs);
this.color = color;
}
fly() {
console.log("flying");
}
getColor() {
return this.color;
}
}
let pegion = new Bird(2, "white");
console.log(pegion.getColor());
Linguagem de código: JavaScript ( javascript )
Métodos de sombreamento
ES6 permite que a classe filha e a classe pai tenham métodos com o mesmo nome. Nesse caso, quando você chama o método de um objeto da classe filha, o método da classe filha irá ocultar o método da classe pai.
A Dog
classe a seguir estende a Animal
classe e redefine o walk()
método:
class Dog extends Animal {
constructor() {
super(4);
}
walk() {
console.log(`go walking`);
}
}
let bingo = new Dog();
bingo.walk(); // go walking
Linguagem de código: JavaScript ( javascript )
Para chamar o método da classe pai na classe filha, você usa super.method(arguments)
assim:
class Dog extends Animal {
constructor() {
super(4);
}
walk() {
super.walk();
console.log(`go walking`);
}
}
let bingo = new Dog();
bingo.walk();
// walking on 4 legs
// go walking
Linguagem de código: JavaScript ( javascript )
Herdando membros estáticos
Além das propriedades e métodos, a classe filha também herda todas as propriedades e métodos estáticos da classe pai. Por exemplo:
class Animal {
constructor(legs) {
this.legs = legs;
}
walk() {
console.log('walking on ' + this.legs + ' legs');
}
static helloWorld() {
console.log('Hello World');
}
}
class Bird extends Animal {
fly() {
console.log('flying');
}
}
Linguagem de código: JavaScript ( javascript )
Neste exemplo, a Animal
classe possui o helloWorld()
método estático e este método está disponível como Bird.helloWorld()
e se comporta da mesma forma que o Animal.helloWorld()
método:
Bird.helloWorld(); // Hello World
Linguagem de código: JavaScript ( javascript )
Herdando de tipos integrados
JavaScript permite estender um tipo integrado como Array , String, Map e Set por meio de herança.
A Queue
classe a seguir estende o Array
tipo de referência. A sintaxe é muito mais limpa do que a Queue
implementada usando o padrão construtor/protótipo .
class Queue extends Array {
enqueue(e) {
super.push(e);
}
dequeue() {
return super.shift();
}
peek() {
return !this.empty() ? this[0] : undefined;
}
empty() {
return this.length === 0;
}
}
var customers = new Queue();
customers.enqueue('A');
customers.enqueue('B');
customers.enqueue('C');
while (!customers.empty()) {
console.log(customers.dequeue());
}
Linguagem de código: JavaScript ( javascript )
Resumo
- Use a
extends
palavra-chave para implementar a herança no ES6. A classe a ser estendida é chamada de classe base ou classe pai. A classe que estende a classe base ou classe pai é chamada de classe derivada ou classe filha. - Chame o
super(arguments)
construtor da classe filha para invocar o construtor da classe pai. - Use
super
palavra-chave para chamar métodos da classe pai nos métodos da classe filha.