Se você é programador java pode imaginar que Traits são como herança múltipla ou mesmo meras interfaces com default methods mas, existe uma diferença fundamental que diferencia os Traits destas duas abordagens:
Veja o exemplo.
Suponha que nossa tarefa seja implementar a seguinte classe abstrata:

abstract class Greetings {
  def sayHello(name: String): String
}

Criamos então a classe abaixo:

class BasicGretings extends Greetings{
  override def sayHello(name: String): String = s"hello $name"
}

Agora vamos criar um Trait que também implementa a classe abstrata Greetings:
Veja que ele chama o método da superclasse e adiciona uma exclamação no final.

trait Exclamation extends Greetings {
  abstract override def sayHello(name: String) = super.sayHello(name) + " !!!!!!"
}

Vamos ainda criar mais um Trait que implementa a classe Greetings. Este converte tudo para maiúsculas

trait Uppercase extends Greetings {
  abstract override def sayHello(name: String) = super.sayHello(name).toUpperCase
}

Agora vamos criar uma classe que além de estender BasicGretting adiciona os 2 Trais

class MegaGreetings extends BasicGretings with Uppercase with Exclamation

Como vimos as classes BasicGretings, Uppercase e Exclamation implementam o método sayHello ao mesmo tempo.
O que acontecera?
1 – Vai prevalecer o método da classe concreta.
2 – Não compila (diamond of death)
3 – Todos os métodos serão chamados.
4 – Somente o método do último trait
Vejamos
resultado
Sim ele vai chamar todos métodos! O da classe concreta e o método de cada trait em cadeia. Iste se chama Stackable Trait Pattern. Podemos usa-lo para adicionar um comportamento de forma totalmente modular.
Veja que eu não precisaria ter criado a classe MegaGreetings que estende de BasicGretings.
Basta eu usar a seguinte sintaxe:
Somente Basic:

scala> val basic1 = new BasicGretings()
scala> basic1.sayHello("World")
res6: String = hello World

Basic com exclamação:

scala> val basic2 = new BasicGretings() with Exclamation
basic2: com.example.BasicGretings with com.example.Exclamation = $anon$1@2cd526ba
scala> basic2.sayHello("World")
res7: String = hello World !!!!!!

Basic com exclamação e maiúsculas:

scala> val basic3 = new BasicGretings() with Exclamation with Uppercase
basic3: com.example.BasicGretings with com.example.Exclamation with com.example.Uppercase = $anon$1@b6a6d85
scala> basic3.sayHello("World")
res8: String = HELLO WORLD !!!!!!

Veja que eu consigo compor o comportamento do meu objeto no momento de instância-lo adicionando e removendo Trais com a palavra with e sem precisar adicionar código na classe BasicGretings. Repare que a implementação no trait chama o super. O que este método faz é desconhecido no momento da criação do Trait. O “bind” é feito dinamicamente.
Essa é umas das coisas que podemos fazer com Trais. Eles são estruturas fundamentais para reutilização de código no scala. No próximo artigo vou falar um pouco sobre rich interfaces.
abcs
Este artigo foi publicado primeiro em: ricardomurad.com

Autor

Wilson Souza é Gerente de Marketing da Bluesoft. Formado e pós Graduado pela Instituição Mackenzie, possui também MBA pela FGV. Wilson tem mais de 10 anos de experiência na área de Relacionamento e Marketing, atuando em diversas áreas e segmentos do mercado.

Deixe aqui o seu comentário