Implement: implementando classes em Mootools
Com implement podemos implementar novas características e funcionalidades nas classes de Mootools, modificando a própria classe ao invés de criar novas classe.Por Miguel Angel Alvarez - Tradução de JML
Publicado em: 16/2/09
Continuamos o
Manual de Mootools com explicações sobre o implement das classes de Mootools. Implement é um método de Class, portanto é um método que terá qualquer nova classe que criamos com Mootools (Lembramos que qualquer classe criada com Mootools na verdade é um objeto da classe Class). Implement serve para modificar uma classe criada anteriormente, adicionado novas propriedades ou métodos.
Para explicar o funcionamento de implement podemos utilizar um exemplo. Imaginemos que temos a classe carro. O carro pode ter cor, modelo e motor, logo a um carro podemos arrancá-lo e pará-lo, movê-lo e detê-lo. Porém, agora imaginemos que necessitamos complicar um pouco a classe carro, para adicionar um número de lugares para passageiros e a possibilidade de encher ou esvaziar tais lugares com pessoas. Então, o que faremos será implementar na classe carro, já criada anteriormente, a propriedade de número de lugares, assim como os métodos de ocupar e desocupar os assentos.
Com implement não se criam novas classes, e sim se modifica. A classe carro será alterada, porque agora terá novas propriedades e funcionalidades, porém não se criará nenhuma classe a partir do carro, e sim que será a mesma classe carro que se modificará.
Para entender melhor implemet temos que vê-lo em comparação com extend. Enquanto que com extend o que se criavam era novas classes que estendiam as anteriores, com implement o que estamos é modificando essas mesmas classes. Caso ainda não tenha ficado claro, com extend criávamos novas classes "filho" que herdavam propriedades e métodos de classes "pai", enquanto que com implement não se cria nenhuma classe nova "filho", e sim que se modifica a classe original que se está implementando.
Para que casos pode servir implement?
Vou dar um exemplo típico que pode nos servir de muita ajuda o método implement. Imaginemos que temos a classe "Animal". Logo, com extend criamos, a partir da classe animal, as classes "Mamíferos" e "Anfíbios". Agora, estendendo a classe "Mamíferos" criamos a classe "Cachorro" e "Gato". Estendendo "Anfíbios" criamos a classe "Rã" e "Salamandra".
Em uma estrutura de herança como a que relatei por colocar um exemplo, agora imaginemos que queremos adicionar uma característica ou funcionalidade específica à classe "Animal", para que todos os animais da hierarquia de herança tenham essa nova funcionalidade ou característica. Poderíamos estender a classe "animal" e criar um "AnimalEstendido", porém isto não modificaria as classes que herdam de "Animal", a não ser que modificássemos o código de todas as classes que dependem de "Animal" para fazer com que, ao invés de estender "Animal", estendessem "AnimalEstendido".
Essa solução, que seria pouco atrativa, por ter que retocar o código de uma série de classes, se poderia solucionar com implement. Com Implement poderíamos modificar diretamente a classe "Animal" e com isso conseguiríamos que mudasse esta e todas as classes que tiver por debaixo na hierarquia de herança. Ou seja, implementando essas novas funcionalidades ou características a "Animal" estaríamos automaticamente incorporando-as aos "Mamíferos", "Anfíbios", "Cachorros", "Rãs"…
Vejamos um exemplo de Implement em um código Javascript com Mootools:
Podemos ter uma classe chamada "Casa", com um código como o que segue:
var Casa = new Class({
aberta: false,
initialize: function(quartos, banheiros){
this.num_quartos = quartos;
this.num_banheiros = banheiros;
},
abrir: function(){
this.aberta = true;
alert('casa aberta');
},
cerrar: function(){
this.aberta = false;
alert('casa fechada');
}
})
Esta classe "Casa" tem uma propriedade "aberta" que à princípio vale "false". Ademais com o construtor initialize se criam duas novas propriedades que são o número de quartos e banheiros. Logo se criaram dois métodos um para abrir() a casa e outro para fechar() a mesma.
Agora vamos ver como se poderia utilizar implement para adicionar novas propriedades e métodos.
Casa.implement({
ocupantes: 0,
ocupar: function(){
if (this.aberta){
if (this.ocupantes < this.num_quartos){
this.ocupantes++;
alert("Ocupei um quarto");
}else{
alert("Não há espaço para mim na casa");
}
}else{
alert("A casa está fechada, não posso entrar");
}
},
desocupar: function(){
if (this.aberta){
if (this.ocupantes > 0){
this.ocupantes--;
alert("Sai da casa e deixei um quarto livre");
}else{
alert("Não há ocupantes na casa");
}
}else{
alert("A casa está fechada, não posso sair");
}
}
});
Vemos que se adicionou uma propriedade chamada "ocupantes", que contém o número de ocupantes da casa, inicialmente sempre igual a zero.
Logo se adicionou com implement dois métodos, ocupar() e desocupar(). O método ocupar primeiro comprova se a casa está aberta e logo se resta espaço nos quartos. Se for assim, adiciona um ao número de ocupantes. O método desocupar() simplesmente olha se a casa está aberta e se há ocupantes e nesse caso diminui um aos ocupantes.
Depois do implement, a classe "Casa" simplesmente terá essas novas propriedades e métodos, porém continuará sendo a mesma classe "Casa", simplesmente modificada.
Poderíamos colocar em funcionamento a classe casa da seguinte maneira:
var minhaCasa = new Casa(2,1);
minhaCasa.ocupar();
minhaCasa.abrir();
minhaCasa.desocupar();
minhaCasa.ocupar();
minhaCasa.ocupar();
minhaCasa.ocupar();
minhaCasa.desocupar();
minhaCasa.ocupar();
Podemos
ver o exemplo em funcionamento em uma página à parte.
Só falta assinalar um pequeno detalhe, que pode ser uma besteira comentar, porém é para que fique claro. Em extend podíamos utilizar parent() para fazer referência à classe pai que estávamos estendendo, desde a classe filha. Porém, em implement, como não se está criando nenhuma classe filha, e sim que se modifica a classe original, não faz sentido utilizar parent().