Mezcla de múltiples rasgos en Scala


Nota rápida: Ejemplos del tutorial Scala para Refugiados de Java Parte 5: Rasgos y Tipos.

Supongamos que tengo los rasgos Estudiante, Trabajador, Mal Pagado y Joven.

¿Cómo podría declarar una clase (no instancia), CollegeStudent, con todos estos rasgos?

Nota: Soy consciente de los casos más simples, como CollegeStudent con uno o dos rasgos:

class CollegeStudent extends Student with Worker
Author: Peter Mortensen, 2009-07-05

2 answers

Es fácil, al declarar una clase, simplemente usa la palabra clave" with " tantas veces como quieras

class CollegeStudent extends Student with Worker with Underpaid with Young

El orden de los rasgos puede ser importante si un rasgo está cambiando el comportamiento de la clase, todo depende de los rasgos que esté usando.

Además, si no quieres tener una clase que siempre use los mismos rasgos, puedes usarlos más tarde:

class CollegeStudent extends Student
new CollegeStudent with Worker with Underpaid with NotSoYoungAnymore
 92
Author: Alexander Stolz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-06 06:14:03

Creo que es muy importante explicar no solo la sintaxis, sino también qué papel juega el orden de los rasgos. Encontré la explicación en Jason Swartz Learning Scala (página 177) bastante esclarecedora.

  • Una clase Scala puede extender múltiples rasgos a la vez, pero las clases JVM pueden extender solo una clase padre. El compilador de Scala resuelve esto creando " copias de cada rasgo para formar una alta jerarquía de una sola columna de la clase y traits ", un proceso conocido como linealización.

  • En este contexto, extender múltiples rasgos con nombres de campo idénticos fallaría en compilar, exactamente el mismo " como si estuviera extendiendo una clase y proporcionando su propia versión de un método, pero no pudo agregar una palabra clave override".

Y dado que determina la forma del árbol de herencia, el orden de linealización es de hecho una cuestión muy importante a considerar. Como ejemplo, class D extends A with B with C (donde A es una clase y B y C son rasgos) se convertiría class D extends C extends B extends A. Las siguientes líneas, también del libro, ilustran eso perfectamente:

trait Base { override def toString = "Base" }
class A extends Base { override def toString = "A->" + super.toString }
trait B extends Base { override def toString = "B->" + super.toString }
trait C extends Base { override def toString = "C->" + super.toString }
class D extends A with B with C { override def toString = "D->" + super.toString }

Una llamada a new D() haría que el REPL imprimiera lo siguiente:

 D->C->B->A->Base

Que refleja perfectamente la estructura del gráfico de herencia linealizada.

 9
Author: fr_andres,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-11 18:36:26