2012-06-22 11 views
40

¿hay alguna forma de ampliar una clase de caso sin tener que elegir nuevos vals constantemente en el camino? Por ejemplo esto no funciona¿Ampliando la clase scala case sin duplicar constantemente los valores de los constructores?

case class Edge(a:Strl, b:Strl) 
case class EdgeQA(a:Strl, b:Strl, right:Int, asked:Int) extends Edge(a,b) 

"a" conflictos con "A", por lo que estoy obligado a cambiar el nombre a A1. Pero no quiero todo tipo de copias públicas adicionales de "a", así que lo hice de forma privada.

case class Edge(a:Strl, b:Strl) 
case class EdgeQA(private val a1:Strl, private val b1:Strl, right:Int, asked:Int) extends Edge(a,b) 

Esto simplemente no me parece limpio ... ¿me falta algo?

Respuesta

46

Como mencionó el comentarista anterior: la extensión de la clase de caso debe evitarse, pero puede convertir su clase Edge en un rasgo.

Si quieres evitar las declaraciones privadas también se pueden marcar las variables como anulación

trait Edge{ 
    def a:Strl 
    def b:Strl 
} 

case class EdgeQA(override val a:Strl, override val b:Strl, right:Int, asked:Int) extends Edge 

No se olvide a preferir def sobre val en los rasgos

+7

Perdemos la ventaja de Edge como una clase independiente: antes de que pudiera ser instanciada y tenía el objeto Factory methods – javadba

+1

pero aún necesito volver a declarar a y b. ¿Qué ocurre si el rasgo tiene algún valor predeterminado para ay ser y deseo usar esos valores por sí mismos? – Sohaib

+5

¿Puedes explicar por qué se prefiere def en los rasgos? – Wolfsblvt

11

Las clases de casos no se pueden extender a través de subclases. O más bien, la subclase de una clase de caso no puede ser una clase de caso en sí misma.

+3

Atrévete a explicar por qué? –

+2

Entonces, ¿por qué hay 'clases de casos finales '? El 'final' _LocalModifier_ es lo que impide la extensión de una' case class', no alguna otra prohibición de idioma. Ver §5.2, p.63 de la [Referencia de Scala] (http://www.scala-lang.org/files/archive/nightly/pdfs/ScalaReference.pdf) –

+3

Final impide extender una clase de caso con cualquier cosa (es decir, caso y no clases de casos), además de la restricción incorporada para extender clases de casos con clases de casos. – jhegedus

23

Esta solución ofrece algunas ventajas sobre el anterior soluciones:

trait BaseEdge { 
    def a: Strl 
    def b: Strl 
} 
case class Edge(a:Strl, b:Strl) extends BaseEdge 
case class EdgeQA(a:Strl, b:Strl, right:Int, asked:Int) extends BaseEdge 

De esta manera:

  • no tiene redundante val s, y
  • tiene 2 clases de casos.
+1

esto es definitivamente mejor – salvob

Cuestiones relacionadas