Curso
DataCamp ha lanzado recientemente su primer curso de Scala: Introduction to Scala. ¡Échale un vistazo!
También te pueden interesar estos tutoriales:
- Beginners Guide to Scala
- IF ELSE in Scala
- Operators in Scala
- Lists in Scala
- Scala Classes and Objects
Introducción
Un trait es un concepto propio de la programación orientada a objetos que permite ampliar la funcionalidad de una clase mediante un conjunto de métodos.
Los traits son parecidos a las interfaces del lenguaje Java. A diferencia de una clase, los traits en Scala no se pueden instanciar y no aceptan argumentos o parámetros. Sin embargo, puedes heredarlos (extenderlos) desde clases y objetos. Dicho esto, los traits proporcionan un conjunto concreto de métodos/funciones que aportan comportamiento a una clase y esperan que la clase implemente otros métodos que parametrizan ese comportamiento.
Un trait que se usa para definir un objeto se crea como una mezcla de métodos reutilizables por distintas clases sin necesidad de herencia múltiple. No obstante, puede haber excepciones en las que dos traits tengan un método con el mismo nombre (colisión de nombres) y deban usarse en una clase; en ese caso, la ambigüedad debe resolverse de forma explícita.
Los traits pueden tener métodos y campos tanto abstractos como no abstractos. Cuando no inicializas un método en un trait, es abstracto; los que sí tienen implementación se consideran no abstractos. En los métodos abstractos, la clase que implementa el trait se encarga de la implementación.
Ahora, veamos rápidamente los traits de Scala con algunos ejemplos.
Sintaxis de los traits en Scala
La sintaxis de un trait en Scala es sencilla: se define con la palabra clave trait seguida del nombre del trait.
trait Trait_Name{
// Variables
// Métodos
}

Como puedes ver en la definición anterior, se definió un trait llamado DataCamp sin variables ni métodos en su interior.
Pase mos a un ejemplo sencillo de traits en Scala para ver con claridad cómo funcionan a nivel de código.
Como se comentó en la introducción, los traits en Scala se heredan en una clase con la palabra clave extends.
class Scala_Tutorial extends DataCamp{
// Variables
// Métodos
}
Definamos un trait llamado Scala_Course, que heredará la clase DataCamp. Dentro del trait definiremos un método abstracto llamado scala(), que implementaremos en la clase 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()
}
}
Ahora ejecutemos el código anterior.

En el ejemplo, el método scala() era abstracto, por lo que su implementación se hizo en la clase que heredó el trait.
Pero ¿qué pasa si ya tienes un método (no abstracto) implementado en el trait? En ese caso, la clase que lo extiende no necesita implementar de nuevo el método ya definido en el trait.
Veámoslo con un ejemplo breve.
trait BMW{
// variables del trait
var make: String = "BMW"
var model: String = "X7"
var fuel: Int = 40
// método del trait: NO ABSTRACTO
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{
// variables de la clase
var make1: String = "Mercedes Benz"
var model1: String = "S350D"
var fuel1: Int = 50
// método de la clase
def Merc_Specs()
{
println("Make of the Car : " + make1);
println("Model of the Car : " + model1);
println("Fuel capacity of the Car : " + fuel1);
}
}
object Main
{
// método main
def main(args: Array[String])
{
// objeto de la clase
var obj = new Car();
println("Calling the Class Method")
obj.Merc_Specs();
println("Calling the Trait Method")
obj.Display();
}
}
Ejecutemos el código anterior:

Ahora que has visto la diferencia entre métodos abstract y non-abstract, veamos qué puede fallar cuando un método abstract no se implementa en la clase que lo hereda o extiende.
Usemos el mismo ejemplo para entenderlo.
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()
}
}
Al ejecutar el código anterior se produce un error, como se muestra a continuación, porque no definiste el método del trait scala() (abstracto) en la clase que lo heredó.

Para que el código funcione, hay dos posibles soluciones:
- Definir el método
scala()en la claseDataCampo - Declarar la clase DataCamp como
abstract.
El último tema de hoy es cómo heredar múltiples traits en una misma clase. Vamos a rematarlo.
trait A{
// métodos
}
trait B{
// métodos
}
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
{
// método main
def main(args: Array[String])
{
// objeto de la clase
var obj = new Car();
println("Calling the BMW Trait")
obj.BMW_Specs();
println();
println("Calling the Merc Trait")
obj.Merc_Specs();
}
}
Por último, ejecutemos el código anterior.

¡Enhorabuena!
Enhorabuena por terminar este tutorial.
Ahora ya sabes qué son los traits en programación y cómo usarlos en Scala. Un buen ejercicio sería proponer una solución cuando el método abstracto no está definido en la clase que lo hereda. Intenta escribir el código y comprueba si compila sin errores. Un pequeño consejo: echa un vistazo a las clases abstractas en Scala.
No dudes en dejar cualquier pregunta sobre este tutorial en los comentarios de abajo.
Y no olvides hacer el nuevo curso de Scala en DataCamp, Introduction to Scala.
