terça-feira, 3 de maio de 2016

Orientação a Objetos: Herança em Javascript

No curso de Criação de Jogos Javascript, utilizamos o jogo Miaus 2.0 para explicar uma das diversas formas de implementarmos herança em Javascript, e aproveitamos para buscar demonstrar as vantagens da Programação Orientada a Objetos.

Vamos mostrar a seguir como utilizamos herança em um exemplo simplificado semelhante ao fonte do Miaus 2.0. No código fonte do Miaus 2.0 vocês podem encontrar esta mesma aplicação de herança de uma forma mais sofisticada.

Por que Utilizamos Herança no Miaus 2.0

No curso de Criação de Jogos Javascript, utilizamos uma função sprites para implementar uma série de ações comuns a todos os elementos da cena. Na função sprites temos funções para desenho (que fazem a exibição do objeto), funções de movimento, de detecção de colisões, entre outras.

Todos os elementos da cena, por sua vez, são criados a partir de funções derivadas de sprites. Isso significa que cada elemento só precisa implementar alguma função quando a mesma tem uma funcionalidade diferente da implementação básica definida na função sprites.

Adicionalmente, podemos armazenar todos os elementos da cena em um vetor único, o qual percorremos chamando as funções de desenho, ciclo, etc. Isso simplifica significativamente o desenvolvimento e manutenção do código, deixando o tratamento de como é feito o desenho, quais ações ocorrem a cada ciclo, sob responsabilidade das funções derivadas de sprite.

Como Implementar Herança em Javascript

Existem diversas formas de implementarmos herança. Abaixo apresentamos a abordagem adotada no jogo Miaus 2.0, utilizando um código mínimo. Você pode testar este código diretamente no console do seu navegador. No caso do Chrome, basta seguir os passos abaixo:

  1. Abra uma janela do Chrome
  2. Digite "about:blank" e dê ENTER
  3. Digite F12
  4. Selecione a aba console 
  5. Copie e cole o código abaixo, e observe os resultados

Código-fonte demonstrando herança em javascript

Selecione a partir daqui e copie:
----------------------------------------------------------------------------
function Pai()
{
  this.funcao_comum = function()
  {
     return "esta função é igual para todos";
  }
}
Pai.prototype.funcao_especifica = function()
{
    return  "esta é uma função do pai";
}

function Filho1()
{
  Pai.call(this);
  this.funcao_especifica = function()
  {
     return "esta é uma função do filho 1";
  }
}
Filho1.prototype = Object.create(Pai.prototype)

function Filho2()
{
  Pai.call(this);
  this.funcao_especifica = function()
  {
     var mensagemPai = Pai.prototype.funcao_especifica.call(this);
     return mensagemPai + " e esta é uma função do filho 2";
  }
}
Filho2.prototype = Object.create(Pai.prototype)


{
  lista = [];
  lista[0] = new Pai();
  lista[1] = new Pai();
  lista[2] = new Pai();
  lista[3] = new Filho1();
  lista[4] = new Filho2();
  for (i = 0; i < 5; i++) {
    console.log(lista[i]);
    console.log(i,lista[i].funcao_comum());
    console.log(i,lista[i].funcao_especifica());
  }

}

----------------------------------------------------------
Marque até aqui, e cole na janela de console de seu navegador


Estudando o Código de Demonstração de Herança

Observe que criamos uma lista de 5 elementos, e fizemos um loop através de cada um dos elementos. Fizemos a chamada a função funcao_comum() e funcao_especifica(), com diferentes resultados. Como funcao_comum() só é implementada na função principal ela é mostrada igual em todas as chamadas do console. Já funcao_especifica() apresenta resultados diferentes em cada uma das funções.

Ocorre que o Javascript utiliza prototype como um ponteiro para um conjunto de funções definidas pela função, e como ponteiro para o prototype da classe superior. Ao utilizarmos Filho1.prototype = Object.create(Pai.prototype), estamos garantindo que toda função não encontrada dentro da função Filho1, será chamada da função Pai, se existir na mesma.

O resultado, se a cópia para o console ocorreu adequadamente, é mostrado a seguir. (Também é perfeitamente possível copiar o javascript para dentro de uma página HTML):

> Pai {}
0 "esta função é igual para todos"
0 "esta é uma função do pai"
> Pai {}
1 "esta função é igual para todos"
1 "esta é uma função do pai"
> Pai {}
2 "esta função é igual para todos"
2 "esta é uma função do pai"
> Filho1 {}
3 "esta função é igual para todos"
3 "esta é uma função do filho 1"
> Filho2 {}
4 "esta função é igual para todos"
4 "esta é uma função do pai e esta é uma função do filho 2"

Como Utilizar o Código do Miaus 2.0

A primeira versão do Miaus está descrita em um curso gratuito, que você pode realizar acessando este link: Curso Básico de Jogos em Javascript.

O código-fonte da versão 2.0 do Miaus também está disponível gratuitamente. Um link neste próprio blog permite abrir diretamente o jogo em si.

O curso Criando Jogos em Javascript, em que trabalhamos de forma mais aprofundada com orientação a objetos e o código fonte do Miaus 2.0, faz parte do Curso Online em Criação de Jogos Digitais.

Se desejar, você pode utilizar livremente o código-fonte do Miaus 2.0, seja para estudo, seja para utilizar como base para a construção de jogos gratuitos ou comerciais.

Links

Nenhum comentário:

Postar um comentário