Groovy - Rasgos

Los rasgos son una construcción estructural del lenguaje que permiten:

  • Composición de comportamientos.
  • Implementación en tiempo de ejecución de interfaces.
  • Compatibilidad con compilación / verificación de tipos estáticos

Pueden verse como interfaces que llevan implementaciones y estados predeterminados. Un rasgo se define mediante la palabra clave rasgo.

A continuación se da un ejemplo de un rasgo:

trait Marks {
   void DisplayMarks() {
      println("Display Marks");
   } 
}

Luego, se puede usar la palabra clave implementar para implementar el rasgo de manera similar a las interfaces.

class Example {
   static void main(String[] args) {
      Student st = new Student();
      st.StudentID = 1;
      st.Marks1 = 10; 
      println(st.DisplayMarks());
   } 
} 

trait Marks { 
   void DisplayMarks() {
      println("Display Marks");
   } 
} 

class Student implements Marks { 
   int StudentID
   int Marks1;
}

Implementación de interfaces

Los rasgos pueden implementar interfaces, en cuyo caso las interfaces se declaran utilizando la palabra clave implements.

A continuación se muestra un ejemplo de un rasgo que implementa una interfaz. En el siguiente ejemplo se pueden observar los siguientes puntos clave.

  • Una interfaz Total se define con el método DisplayTotal.

  • El rasgo Marks implementa la interfaz Total y, por lo tanto, debe proporcionar una implementación para el método DisplayTotal.

class Example {
   static void main(String[] args) {
      Student st = new Student();
      st.StudentID = 1;
      st.Marks1 = 10;
		
      println(st.DisplayMarks());
      println(st.DisplayTotal());
   } 
} 

interface Total {
   void DisplayTotal() 
} 

trait Marks implements Total {
   void DisplayMarks() {
      println("Display Marks");
   }
	
   void DisplayTotal() {
      println("Display Total"); 
   } 
} 

class Student implements Marks { 
   int StudentID
   int Marks1;  
}

El resultado del programa anterior sería:

Display Marks 
Display Total

Propiedades

Un rasgo puede definir propiedades. A continuación se muestra un ejemplo de un rasgo con una propiedad.

En el siguiente ejemplo, Marks1 de tipo integer es una propiedad.

class Example {
   static void main(String[] args) {
      Student st = new Student();
      st.StudentID = 1;
		
      println(st.DisplayMarks());
      println(st.DisplayTotal());
   } 
	
   interface Total {
      void DisplayTotal() 
   } 
	
   trait Marks implements Total {
      int Marks1;
		
      void DisplayMarks() {
         this.Marks1 = 10;
         println(this.Marks1);
      }
		
      void DisplayTotal() {
         println("Display Total");
      } 
   } 
	
   class Student implements Marks {
      int StudentID 
   }
}

El resultado del programa anterior sería:

10 
Display Total

Composición de comportamientos

Los rasgos se pueden utilizar para implementar la herencia múltiple de forma controlada, evitando el problema del diamante. En el siguiente ejemplo de código, hemos definido dos rasgos:Marks y Total. Nuestra clase de estudiantes implementa ambos rasgos. Dado que la clase del estudiante extiende ambos rasgos, puede acceder a ambos métodos:DisplayMarks y DisplayTotal.

class Example {
   static void main(String[] args) {
      Student st = new Student();
      st.StudentID = 1;
		
      println(st.DisplayMarks());
      println(st.DisplayTotal()); 
   } 
} 

trait Marks {
   void DisplayMarks() {
      println("Marks1");
   } 
} 

trait Total {
   void DisplayTotal() { 
      println("Total");
   } 
}  

class Student implements Marks,Total {
   int StudentID 
}

El resultado del programa anterior sería:

Total 
Marks1

Extendiendo rasgos

Los rasgos pueden extender otro rasgo, en cuyo caso debe usar el extendspalabra clave. En el siguiente ejemplo de código, estamos ampliando el rasgo Total con el rasgo Marcas.

class Example {
   static void main(String[] args) {
      Student st = new Student();
      st.StudentID = 1;
      println(st.DisplayMarks());
   } 
} 

trait Marks {
   void DisplayMarks() {
      println("Marks1");
   } 
} 

trait Total extends Marks {
   void DisplayMarks() {
      println("Total");
   } 
}  

class Student implements Total {
   int StudentID 
}

El resultado del programa anterior sería:

Total