2010-03-11 16 views
5

Aquí es una simplificación de las clases que tengo:En Scala, ¿puedo anular un campo concreto que contiene una lista y anexarle algo en la subclase?

trait RequiredThings { 
    val requiredThings: Seq[String] 
} 

class SimpleCalculator with RequiredThings { 
    val requiredThings = List("a", "b") 
} 

class ComplicatedCalculator extends SimpleCalculator with RequiredThings { 
    self: SimpleCalculator => 
    override val requiredThings:List[String] = List("c") ::: self.requiredThings 
} 

En esta versión, estoy usando una anotación de tipo auto, pero no estoy completamente seguro de que es el camino a seguir. Creo que probablemente podría hacerlo funcionar convirtiendo el requiredThings en un método completo, pero me gustaría probarlo como campo.

solución final:

trait RequiredThings { 
    def requiredThings: Seq[String] 
} 

class SimpleCalculator with RequiredThings { 
    def requiredThings = List("a", "b") 
} 

class ComplicatedCalculator extends SimpleCalculator with RequiredThings { 
    override def requiredThings:List[String] = List("c") ::: super.requiredThings 
} 

Respuesta

7

Sí, las supercompetentes a métodos "heredados" a través del tipo propio todavía no están implementadas. Esto cambiará (algo) pronto. Mientras tanto, debes usar la herencia en su lugar.

+0

Esto es lo que terminé haciendo. He actualizado la pregunta con la versión final de mi código. –

+0

"Esto cambiará (algo) pronto". No recuerdo de la lista de correo donde alguien dijo que esto podría cambiar. ¿Podrías mostrarme dónde obtuviste esa información? Gracias. – Eric

+2

@Eric: no estoy seguro si esto se ha publicado alguna vez en la lista de correo, pero estoy en el equipo de Scala, y Martin ha aceptado (en principio) esa característica. Mientras tanto, me empantané con otras cosas, y hay algunos problemas de implementación no triviales. –

3

Tiene sentido tiene requiredThings como def al menos en el trait - esto le dará más flexibilidad

+0

Eso tiene mucho sentido. Lo he hecho en mi solución. –

4

divertido lo suficiente, di un paso sobre el mismo tema ayer.

La forma en que se implementan los self types actualmente, si reemplaza un método (o valor) no hay forma de referirse al método reemplazado.

El siguiente bucle:

class A { def foo = "a" } 
trait B { self: A => override def foo = self.foo + "b" } 

(nota: no se puede llamar super.foo, el padre de B es ScalaObject, no A)

También probé con una indirecta más, pero el programa sigue bucles.

class A { def foo = "a"; def fooA = A.this.foo } 
trait B { this: A => override def foo = fooA + "b" } 

Actualmente hay trabajo en auto tipos, quizás esto cambie.

Cuestiones relacionadas