Enums é uma forma que posso trabalhar com valores predefinidos de forma constantes, uma vantagem disso é conseguirmos uma segurança em tempo de compilação, pois desta forma no momento que seu app estiver compilando, facilmente será identificado caso algum valor incorreto esteja sendo utilizado.
Vamos ao seguinte exemplo em que tenho uma classe Funcionario onde tem um método chamado imprimirRegimeContratacao que recebe uma String representando o tipo de contratação e me retorna uma descrição.
void main() { | |
final funcionario = Funcionario(); | |
print(funcionario.imprimirRegimeContratacao('CLT')); | |
} | |
class Funcionario { | |
String imprimirRegimeContratacao(String tipoContratacao) { | |
if (tipoContratacao == 'CLT') { | |
return 'Contrato CLT'; | |
} else if (tipoContratacao == 'PJ') { | |
return 'Contrato PJ'; | |
} else if (tipoContratacao == 'Estagio') { | |
return 'Contrato ESTAGIARIO'; | |
} else { | |
return 'Contrato não identificado'; | |
} | |
} | |
} |
Isto me retornará o seguinte resultado.
Entretanto, se ao invés de passar “CLT” como parâmetro eu passar “clt”(em minúsculo) ocorrerá um problema.
void main() { | |
final funcionario = Funcionario(); | |
print(funcionario.imprimirRegimeContratacao('clt')); | |
} | |
class Funcionario { | |
String imprimirRegimeContratacao(String tipoContratacao) { | |
if (tipoContratacao == 'CLT') { | |
return 'Contrato CLT'; | |
} else if (tipoContratacao == 'PJ') { | |
return 'Contrato PJ'; | |
} else if (tipoContratacao == 'Estagio') { | |
return 'Contrato ESTAGIARIO'; | |
} else { | |
return 'Contrato não identificado'; | |
} | |
} | |
} |
O problema do código acima é que ele está muito aberto para que ele aceite qualquer tipo de informação, este é um ótimo tipo de cenário para a utilização de ENUMERADORES, utilizando a palavra enum posso facilmente criar um enumerador.
void main() { | |
final funcionario = Funcionario(); | |
print(funcionario.imprimirRegimeContratacao(TipoContratacao.clt)); | |
} | |
enum TipoContratacao { | |
clt, | |
pj, | |
estagio, | |
} | |
class Funcionario { | |
String imprimirRegimeContratacao(TipoContratacao tipoContratacao) { | |
if (tipoContratacao == TipoContratacao.clt) { | |
return 'Contrato CLT'; | |
} else if (tipoContratacao == TipoContratacao.pj) { | |
return 'Contrato PJ'; | |
} else if (tipoContratacao == TipoContratacao.estagio) { | |
return 'Contrato ESTAGIARIO'; | |
} else { | |
return 'Contrato não identificado'; | |
} | |
} | |
} |
Desta forma eu não consigo mais passar um parâmetro inexistente, pois assim já estão predefinidos os valores que serão tratados.
Agora imagine que precisamos de um método que irá calcular o salário liquido do funcionário que irá receber o salário bruto e descontar o imposto de acordo com o tipo de contratação.
void main() { | |
final funcionario = Funcionario(TipoContratacao.clt); | |
print(funcionario.calcularPagamentLiquido(2000)); | |
} | |
enum TipoContratacao { | |
clt, | |
pj, | |
estagio, | |
} | |
class Funcionario { | |
final TipoContratacao tipoContratacao; | |
Funcionario(this.tipoContratacao); | |
String imprimirRegimeContratacao() { | |
if (tipoContratacao == TipoContratacao.clt) { | |
return 'Contrato CLT'; | |
} else if (tipoContratacao == TipoContratacao.pj) { | |
return 'Contrato PJ'; | |
} else if (tipoContratacao == TipoContratacao.estagio) { | |
return 'Contrato ESTAGIARIO'; | |
} else { | |
return 'Contrato não identificado'; | |
} | |
} | |
calcularPagamentLiquido(double salarioBruto) { | |
return salarioBruto - (salarioBruto * valorImposto(tipoContratacao)); | |
} | |
double valorImposto(TipoContratacao tipoContratacao) { | |
if (tipoContratacao == TipoContratacao.clt) { | |
return 0.2; | |
} else if (tipoContratacao == TipoContratacao.pj) { | |
return 0.1; | |
} else if (tipoContratacao == TipoContratacao.estagio) { | |
return 0.0; | |
} else { | |
return 0.0; | |
} | |
} | |
} |
![](https://res.cloudinary.com/practicaldev/image/fetch/s--hnbMXhye--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AihpxZNj4JRFiS-C5Tstjfw.png)
No dart podemos colocar o método que retorna a porcentagem de imposto dentro do enum, desta forma toda vez que for utilizar deste enum já tenho predefinido a porcentagem que ele irá pagar, pois ele é um valor constante.
Antigamente (antes do Dart 2.17 e Flutter 3.0) precisamos fazer isto através de extensions e com isso conseguimos criar métodos dentro de nosso enum.
void main() { | |
final funcionario = Funcionario(TipoContratacao.pj); | |
print(funcionario.calcularPagamentLiquido(2000)); | |
} | |
enum TipoContratacao { | |
clt, | |
pj, | |
estagio, | |
} | |
extension TipoContratacaoExt on TipoContratacao { | |
String get nome { | |
switch (this) { | |
case TipoContratacao.clt: | |
return 'Contrato CLT'; | |
case TipoContratacao.pj: | |
return 'Contrato PJ'; | |
case TipoContratacao.estagio: | |
return 'Contrato Estágio'; | |
default: | |
return 'Não identificado'; | |
} | |
} | |
double valorImposto(double salarioBruto) { | |
var imposto = 0.0; | |
switch (this) { | |
case TipoContratacao.clt: | |
imposto = 0.2; | |
break; | |
case TipoContratacao.pj: | |
imposto = 0.1; | |
break; | |
case TipoContratacao.estagio: | |
imposto = 0.0; | |
break; | |
default: | |
imposto = 0.0; | |
} | |
return salarioBruto * imposto; | |
} | |
} | |
class Funcionario { | |
final TipoContratacao tipoContratacao; | |
Funcionario(this.tipoContratacao); | |
String imprimirRegimeContratacao() { | |
return tipoContratacao.nome; | |
} | |
calcularPagamentLiquido(double salarioBruto) { | |
return salarioBruto - tipoContratacao.valorImposto(salarioBruto); | |
} | |
} |
No Flutter 3.0 tivemos o suporte ao Dart 2.17 que nos trouxe melhorias nos enumeradores possibilitando criarmos enums mais ricos com métodos e atributos, não necessitando criar extensions.
Desta forma podemos retirar a extension e passar todos os métodos para dentro do enum
void main() { | |
final funcionario = Funcionario(TipoContratacao.estagio); | |
print(funcionario.calcularPagamentLiquido(2000)); | |
} | |
enum TipoContratacao { | |
clt, | |
pj, | |
estagio; | |
String get nome { | |
switch (this) { | |
case TipoContratacao.clt: | |
return 'Contrato '; | |
case TipoContratacao.pj: | |
return 'Contrato PJ'; | |
case TipoContratacao.estagio: | |
return 'Contrato Estágio'; | |
} | |
} | |
double valorImposto(double salarioBruto) { | |
var imposto = 0.0; | |
switch (this) { | |
case TipoContratacao.clt: | |
imposto = 0.2; | |
break; | |
case TipoContratacao.pj: | |
imposto = 0.1; | |
break; | |
case TipoContratacao.estagio: | |
imposto = 0.0; | |
break; | |
} | |
return salarioBruto * imposto; | |
} | |
final double imposto; | |
} | |
class Funcionario { | |
final TipoContratacao tipoContratacao; | |
Funcionario(this.tipoContratacao); | |
String imprimirRegimeContratacao() { | |
return tipoContratacao.nome; | |
} | |
calcularPagamentLiquido(double salarioBruto) { | |
return salarioBruto - tipoContratacao.valorImposto(salarioBruto); | |
} | |
} |
Agora também podemos criar propriedades dentro do enum para pré definir valores que serão constantes (ESTAS PROPRIEDADES DEVEM SER FINAL E IREMOS PASSAR NO CONSTRUTOR)
void main() { | |
final funcionario = Funcionario(TipoContratacao.clt); | |
print(funcionario.calcularPagamentLiquido(2000)); | |
} | |
enum TipoContratacao { | |
clt(0.2), | |
pj(0.2), | |
estagio(0); | |
const TipoContratacao(this.imposto); | |
final double imposto; | |
String get nome { | |
switch (this) { | |
case TipoContratacao.clt: | |
return 'Contrato '; | |
case TipoContratacao.pj: | |
return 'Contrato PJ'; | |
case TipoContratacao.estagio: | |
return 'Contrato Estágio'; | |
} | |
} | |
double valorImposto(double salarioBruto) { | |
return salarioBruto * imposto; | |
} | |
} | |
class Funcionario { | |
final TipoContratacao tipoContratacao; | |
Funcionario(this.tipoContratacao); | |
String imprimirRegimeContratacao() { | |
return tipoContratacao.nome; | |
} | |
calcularPagamentLiquido(double salarioBruto) { | |
return salarioBruto - tipoContratacao.valorImposto(salarioBruto); | |
} | |
} |
Também posso trabalhar com contratos no enum, para predefinir métodos dos enums que irão implementá-los
void main() { | |
final funcionario = Funcionario(TipoContratacao.clt); | |
final funcionario2 = Funcionario(TipoContratacao.pj); | |
print(funcionario.igual(funcionario2)); | |
print(funcionario.differenca(funcionario2)); | |
} | |
abstract class Comparar<T> { | |
bool igual(T outro); | |
double differenca(T outro); | |
} | |
enum TipoContratacao implements Comparar<TipoContratacao> { | |
clt(0.2), | |
pj(0.1), | |
estagio(0); | |
const TipoContratacao(this.imposto); | |
final double imposto; | |
String get nome { | |
switch (this) { | |
case TipoContratacao.clt: | |
return 'Contrato '; | |
case TipoContratacao.pj: | |
return 'Contrato PJ'; | |
case TipoContratacao.estagio: | |
return 'Contrato Estágio'; | |
} | |
} | |
double valorImposto(double salarioBruto) { | |
return salarioBruto * imposto; | |
} | |
@override | |
bool igual(TipoContratacao outro) => outro.imposto == imposto; | |
@override | |
double differenca(TipoContratacao outro) => outro.imposto - imposto; | |
} | |
class Funcionario { | |
final TipoContratacao tipoContratacao; | |
Funcionario(this.tipoContratacao); | |
String imprimirRegimeContratacao() { | |
return tipoContratacao.nome; | |
} | |
calcularPagamentLiquido(double salarioBruto) { | |
return salarioBruto - tipoContratacao.valorImposto(salarioBruto); | |
} | |
bool igual(Funcionario outro) => tipoContratacao.igual(outro.tipoContratacao); | |
double differenca(Funcionario outro) => | |
tipoContratacao.differenca(outro.tipoContratacao); | |
} |
![](https://res.cloudinary.com/practicaldev/image/fetch/s--u7TK2wvr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AI42t5ClTPiB5fy155_3xGA.png)
Desta forma seus enumeradores ficam muito mais poderosos e muito mais legíveis, legal essa nova alteração né?
Tem vários exemplos em meu github entre, compartilhe e dê seu star em meu github :)
https://github.com/toshiossada
Entre em nosso discord para interagir com a comunidade: https://discord.com/invite/flutterbrasil
https://linktr.ee/flutterbrasil
Top comments (0)