Skip to content

13. As classes

Image

Apresentamos aqui as classes de ECMAScript 6. Em primeiro lugar, mostramos que as funções já podem ser utilizadas como classes.

13.1. script [class-00]

O script seguinte mostra uma utilização invulgar das funções. Aqui, utilizamo-las como objetos.


'use strict';
// uma função pode ser utilizada como um objeto

// uma estrutura vazia
function f() {

}
// à qual são atribuídas propriedades a partir do exterior
f.prop1 = "val1";
f.show = function () {
  console.log(this.prop1);
}
// utilização de f
f.show();

// uma função g que funciona como uma classe
function g() {
  this.prop2 = "val2";
  this.show = function () {
    console.log(this.prop2);
  }
}
// instanciação da função com [new]
new g().show();

Comentários

  • linhas 5-7: o corpo da função f não define nenhuma propriedade;
  • linhas 9-12: são atribuídas propriedades à função f a partir do exterior;
  • linha 14: utilização da função (objeto) f. Note-se que não se escreve [f()], mas simplesmente [f]. Trata-se aqui da notação de um objeto;
  • linhas 17-22: define-se uma função [g] como se fosse uma classe com propriedades e métodos;
  • linha 24: a função [g] é instanciada por [new g()];

Resultados da execução


[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Data\st-2019\dev\es6\javascript\classes\class-00.js"
val1
val2

A função ES6 introduziu o conceito de classe, o que nos permite agora evitar recorrer a funções para obter classes.

13.2. script [class-01]

O script [class-01] apresenta uma classe [Personne]:


// classe
class Personne {

  // construtor
  constructor(nom, prénom, âge) {
    this.nom = nom;
    this.prénom = prénom;
    this.âge = âge;
  }

  // getters e setters
  get nom() {
    return this._nom;
  }
  set nom(value) {
    this._nom = value;
  }

  get prénom() {
    return this._prénom;
  }
  set prénom(value) {
    this._prénom = value;
  }

  get âge() {
    return this._âge;
  }
  set âge(value) {
    this._âge = value;
  }

  // toString em JSON
  toString() {
    return JSON.stringify(this);
  }
}

// chamada da classe
function main() {
  const personne = new Personne("Poirot", "Hercule", 66);
  console.log("personne=", personne.toString(), typeof (personne), personne instanceof (Personne));
}

// chamada do método main
main();

Comentários

  • linha 2: a palavra-chave [class] designa uma classe;
  • linhas 5-9: a palavra-chave [constructor] designa o construtor da classe. Só pode existir, no máximo, um. Serve para construir e inicializar uma instância da classe. Note-se que não há declaração das propriedades [nom, prénom, âge];
  • linhas 11-36: propriedades da classe. Encontramos aqui elementos já abordados no parágrafo sobre objetos 4, na página 44. Apenas a sintaxe difere;
  • linha 41: criação de um objeto do tipo [Personne]. A partir de agora, o objeto [personne] é utilizado como um objeto literal. [typeof (personne)] é igual a «object» e a expressão [personne instanceof (Personne)] é verdadeira. É, portanto, possível determinar o tipo exato de uma instância de classe;

Resultados da execução


[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Data\st-2019\dev\es6\javascript\classes\class-01.js"
personne= {"_nom":"Poirot","_prénom":"Hercule","_âge":66} object true

13.3. script [class-02]

Este script demonstra a possibilidade de herdar de uma classe com a palavra-chave [extends].

Em primeiro lugar, isolamos a classe [Personne] num módulo [Personne.js]:


// classe
class Personne {

  // construtor
  constructor(nom, prénom, âge) {
    this.nom = nom;
    this.prénom = prénom;
    this.âge = âge;
  }

  // getters e setters
  get nom() {
    return this._nom;
  }
  set nom(value) {
    this._nom = value;
  }

  get prénom() {
    return this._prénom;
  }
  set prénom(value) {
    this._prénom = value;
  }

  get âge() {
    return this._âge;
  }
  set âge(value) {
    this._âge = value;
  }

  // toString em JSON
  toString() {
    return JSON.stringify(this);
  }
}
// exportar classe
export default Personne;
  • linha 39: exportamos a classe [Personne] para que os scripts a possam importar;

O script [class-02] cria uma classe [Enseignant] derivada da classe [Personne]:


// importações
import Personne from './Personne';

// classe
class Enseignant extends Personne {

  // construtor
  constructor(nom, prénom, âge, discipline) {
    super(nom, prénom, âge);
    this.discipline = discipline;
  }

  // getters e setters
  get discipline() {
    return this._discipline;
  }
  set discipline(value) {
    this._discipline = value;
  }

}

// chamada da classe
function main() {
  const enseignant = new Enseignant("Poirot", "Hercule", 66, "détective");
  console.log("enseignant=", enseignant.toString(), typeof (enseignant), enseignant instanceof Enseignant);
}

// chamada ao método main
main();

Comentários

  • linha 2: importa-se a classe [Personne] a partir do módulo [Personne.js], que se encontra na mesma pasta que [class-02];
  • linha 5: a classe [Enseignant] estende (herda da) classe [Personne] com a palavra-chave [extends]: esta adiciona-lhe uma propriedade [_discipline] com os getter/setter correspondentes;
  • linhas 8-11: o construtor da classe [Enseignant] recebe quatro valores para inicializar as quatro propriedades da classe;
  • linha 9: a palavra-chave [super] chama o construtor da classe pai [Personne], que irá, assim, inicializar as propriedades [_nom, _prénom, _âge];
  • linha 10: inicializa-se a propriedade [_discipline], que pertence à classe [Enseignant];
  • linhas 14-19: o getter e o setter da propriedade [_discipline];
  • linha 25: cria-se um objeto do tipo [Enseignant];
  • linha 26: utiliza-se o método [enseignant.toString()]. A classe [Enseignant] não possui este método. É então o método da sua classe pai que é automaticamente utilizado. Este método faz com que a expressão [JSON.stringify(this)] — em que [this] será, neste caso, um objeto [Enseignant] e não um objeto [Personne] — seja avaliada corretamente. É o que se denomina, na programação orientada para objetos, polimorfismo de classes. Um termo complexo para o JavaScript, que não é uma linguagem orientada para objetos. No entanto, o JavaScript faz aqui o que se espera dele: apresenta corretamente um professor;

Os resultados da execução são os seguintes:


[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Data\st-2019\dev\es6\javascript\classes\class-02.js"
enseignant= {"_nom":"Poirot","_prénom":"Hercule","_âge":66,"_discipline":"détective"} object true
  • linha 2: o JavaScript reconhece corretamente que a variável [enseignant] é do tipo [Enseignant];

13.4. script [class-03]

O script [class-03] mostra que uma classe filha pode redefinir propriedades e métodos da sua classe pai. Aqui, redefinimos o método [toString] da classe pai:


// importações
import Personne from './Personne';

// classe
class Enseignant extends Personne {

  // construtor
  constructor(nom, prénom, âge, discipline) {
    super(nom, prénom, âge);
    this.discipline = discipline;
  }

  // getters e setters
  get discipline() {
    return this._discipline;
  }
  set discipline(value) {
    this._discipline = value;
  }

  // redefinição de toString
  toString() {
    return "[Enseignant]" + JSON.stringify(this);
  }
}

// chamada da classe
function main() {
  const enseignant = new Enseignant("Poirot", "Hercule", 66, "détective");
  console.log("enseignant=", enseignant.toString(), typeof (enseignant), enseignant instanceof Enseignant);
}

// chamada à função main
main();

Os resultados da execução são os seguintes:


[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Data\st-2019\dev\es6\javascript\classes\class-03.js"
enseignant= [Enseignant]{"_nom":"Poirot","_prénom":"Hercule","_âge":66,"_discipline":"détective"} object true

13.5. script [class-04]

O script [class-04] demonstra novamente o polimorfismo em ação: quando uma função espera um parâmetro formal do tipo [Personne], é possível passar um tipo derivado, como o [Enseignant]. Com efeito, devido à derivação, o tipo [Enseignant] possui todos os atributos do tipo [Personne].

Em primeiro lugar, isolamos o tipo [Enseignant] num módulo [Enseignant.js]:


// importações
import Personne from './Personne';

// classe
class Enseignant extends Personne {

  // construtor
  constructor(nom, prénom, âge, discipline) {
    super(nom, prénom, âge);
    this.discipline = discipline;
  }

  // getters e setters
  get discipline() {
    return this._discipline;
  }
  set discipline(value) {
    this._discipline = value;
  }

}

// exportação de classe
export default Enseignant;
  • linha 24: a classe [Enseignant] é exportada para que outros scripts a possam importar;

O script [class-04] é o seguinte:


// importações
import Enseignant from './Enseignant';
import Personne from './Personne';

// função que aceita uma pessoa como parâmetro
function show(personne) {
  // em todos os casos
  console.log("paramètre=", personne.toString(), typeof (personne));
  // instância de Pessoa
  if (personne instanceof Personne) {
    console.log("personne=", personne.toString());
  }
  // instância de Professor
  if (personne instanceof Enseignant) {
    console.log("enseignant=", personne.toString());
  }
}

// chamada da função show com um professor
show(new Enseignant("Poirot", "Hercule", 66, "détective"));
show(new Personne("Marple", "Miss", 70));
  • linha 6: a função [show] espera um tipo [Personne] ou derivado;
  • linha 8: é apresentada a cadeia do parâmetro e o seu tipo. Encontraremos [object];
  • linhas 10-16: é possível determinar se se trata de um tipo [Personne] ou de um tipo [Enseignant]. O código pode, portanto, ser adaptado ao tipo real do parâmetro;

Os resultados da execução são os seguintes:


[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Data\st-2019\dev\es6\javascript\classes\class-04.js"
paramètre= {"_nom":"Poirot","_prénom":"Hercule","_âge":66,"_discipline":"détective"} object
personne= {"_nom":"Poirot","_prénom":"Hercule","_âge":66,"_discipline":"détective"}
enseignant= {"_nom":"Poirot","_prénom":"Hercule","_âge":66,"_discipline":"détective"}
paramètre= {"_nom":"Marple","_prénom":"Miss","_âge":70} object
personne= {"_nom":"Marple","_prénom":"Miss","_âge":70}
  • linhas 4 e 6: o JavaScript reconhece corretamente o tipo das instâncias da classe;