Curso
A DataCamp lançou recentemente seu primeiro curso de Scala: Introduction to Scala. Confira!
Você também pode se interessar pelos seguintes tutoriais:
- Beginners Guide to Scala
- IF ELSE in Scala
- Operators in Scala
- Lists in Scala
- Scala Classes and Objects
Introdução
Trait é um conceito predominantemente usado em programação orientada a objetos, que permite estender a funcionalidade de uma classe por meio de um conjunto de métodos.
Traits são semelhantes, em espírito, às interfaces na linguagem Java. Diferente de uma classe, traits em Scala não podem ser instanciadas e não recebem argumentos ou parâmetros. No entanto, você pode herdá-las (estendê-las) em classes e objetos. Dito isso, traits fornecem um conjunto específico de métodos/funções que adicionam comportamento a uma classe e esperam que a classe implemente alguns métodos que irão parametrizar esse comportamento.
Um trait usado para definir um objeto é criado como uma combinação de métodos que podem ser aproveitados por diferentes classes sem exigir herança múltipla. Porém, podem existir exceções em que dois traits possuem um método com o mesmo nome (colisão de nomes) e precisam ser usados por uma classe — nesse caso, a ambiguidade deve ser resolvida explicitamente.
Traits podem ter métodos e campos abstratos e não abstratos como membros. Quando você não inicializa um método em um trait, ele é abstrato; já os que são inicializados são chamados de não abstratos. Nos métodos abstratos, a classe que implementa o trait fica responsável pela implementação.
Agora, vamos entender rapidamente os traits em Scala com a ajuda de alguns exemplos!
Sintaxe de trait em Scala
A sintaxe de um trait em Scala é direta: usa-se a palavra-chave trait seguida do nome do trait.
trait Trait_Name{
// Variables
// Methods
}

Como você pode ver na definição acima, foi criado um trait chamado DataCamp, sem variáveis ou métodos definidos dentro dele.
Vamos para um exemplo simples de traits em Scala, que vai trazer mais clareza de como funcionam na prática.
Como discutido na introdução, os traits em Scala são herdados por uma classe usando a palavra-chave extends.
class Scala_Tutorial extends DataCamp{
// Variables
// Methods
}
Vamos definir um trait chamado Scala_Course, que será herdado pela classe DataCamp. Dentro do trait, você vai definir um método abstrato chamado scala(), que será implementado na classe DataCamp.
trait Scala_Course{
def scala()
}
class DataCamp extends Scala_Course{
def scala(){
println("DataCamp has recently launched there first Scala course")
}
}
object Main{
def main(args:Array[String]){
var a = new DataCamp()
a.scala()
}
}
Agora vamos executar o código acima.

No exemplo acima, o método scala() era abstrato e, portanto, sua implementação foi feita na classe que herdou o trait.
Mas e se você tiver um método (não abstrato) já implementado no trait? Nesse caso, a classe que estende esse trait não precisa implementar novamente o método que já está definido no trait.
Vamos entender com um exemplo simples.
trait BMW{
// trait variables
var make: String = "BMW"
var model: String = "X7"
var fuel: Int = 40
// trait method: NON-ABSTRACT
def Display()
{
println("Make of the Car : " + make);
println("Model of the Car : " + model);
println("Fuel capacity of the Car : " + fuel);
}
}
class Car extends BMW{
// class variables
var make1: String = "Mercedes Benz"
var model1: String = "S350D"
var fuel1: Int = 50
// Class method
def Merc_Specs()
{
println("Make of the Car : " + make1);
println("Model of the Car : " + model1);
println("Fuel capacity of the Car : " + fuel1);
}
}
object Main
{
// Main method
def main(args: Array[String])
{
// Class object
var obj = new Car();
println("Calling the Class Method")
obj.Merc_Specs();
println("Calling the Trait Method")
obj.Display();
}
}
Vamos executar o código acima:

Agora que você entendeu a diferença entre métodos abstract e non-abstract, veja o que pode dar errado quando um método abstract não é implementado na classe que o herda ou estende.
Vamos usar o mesmo exemplo para entender esse conceito.
trait Scala_Course{
def scala()
}
class DataCamp extends Scala_Course{
def print(){
println("Error: Class DataCamp needs to be Abstract")
}
}
object Main{
def main(args:Array[String]){
var a = new DataCamp()
a.print()
}
}
Executar o código acima resulta em erro, como mostrado abaixo, pois você não definiu o método do trait scala() (abstrato) na classe que o herdou.

Para fazer o código acima funcionar, há duas soluções possíveis:
- Definir o método
scala()na classeDataCampou - Definir a classe DataCamp como
abstract.
O último tópico do tutorial de hoje é como herdar múltiplos traits em uma mesma classe. Vamos finalizar rapidamente.
trait A{
// methods
}
trait B{
// methods
}
class C extends A with B{
}
trait BMW{
var make: String = "BMW"
var model: String = "X7"
var fuel: Int = 40
}
trait Merc{
var make1: String = "Mercedes Benz"
var model1: String = "S350D"
var fuel1: Int = 50
}
class Car extends BMW with Merc{
def BMW_Specs()
{
println("Make of the Car : " + make);
println("Model of the Car : " + model);
println("Fuel capacity of the Car : " + fuel);
}
def Merc_Specs()
{
println("Make of the Car : " + make1);
println("Model of the Car : " + model1);
println("Fuel capacity of the Car : " + fuel1);
}
}
object Main
{
// Main method
def main(args: Array[String])
{
// Class object
var obj = new Car();
println("Calling the BMW Trait")
obj.BMW_Specs();
println();
println("Calling the Merc Trait")
obj.Merc_Specs();
}
}
Por fim, vamos executar o código acima.

Parabéns!
Parabéns por concluir este tutorial.
Agora você sabe o que são Traits em programação e como usá-los em Scala. Um bom exercício é encontrar uma solução para o caso de um método abstrato não estar definido na classe que o herdou. Tente escrever o código e veja se ele roda sem erro de compilação. Uma dica: vale dar uma olhada em Abstract Classes em Scala.
Fique à vontade para deixar suas dúvidas sobre este tutorial na seção de comentários abaixo.
E não esqueça de fazer o novo curso de Scala na DataCamp, Introduction to Scala.
