2011-08-26 10 views
17

Actualmente estoy aprendiendo sobre Scala y tengo algunos problemas para diseñar mis clases de casos. Necesito dos clases de casos que tengan las mismas propiedades. Así que pensé que sería una buena idea heredar de una clase base abstracta que define estas propiedades. Sin embargo, este código no compilaClases de casos que heredan de la clase abstracta

abstract class Resource(val uri : String) 

case class File(uri : String) extends Resource(uri) 
case class Folder(uri : String) extends Resource(uri) 

porque uri en los constructores de clase caso puede sobrescribir la propiedad uri de la clase base.

¿Cuál sería la forma correcta de diseñar esto?

Quiero ser capaz de hacer algo como esto

val arr = Array[Resource](File("test"), Folder("test2")) 

arr.foreach { r : Resource => r match { 
    case f : File => println("It's a file") 
    case f : Folder => println("It's a folder") 
} } 

El código Java "equivalente" debe ser algo como

abstract class Resource { 
    private String uri; 

    public Resource(String uri) { 
     this.uri = uri 
    } 

    public String getUri() { 
     return uri; 
    } 
} 

// same for Folder 
class File extends Resource { 
    public File(String uri) { 
     super(uri); 
    } 
} 

Respuesta

25

La sintaxis correcta debe ser:

abstract class Resource { 
    val uri: String 
} 

case class File(uri : String) extends Resource 
case class Folder(uri : String) extends Resource 


Stream[Resource](File("test"), Folder("test2")) foreach { 
    r : Resource => r match { 
    case f : File => println("It's a file") 
    case f : Folder => println("It's a folder") 
} } 

EDITAR

Sin clases de casos:

abstract class Resource(val uri : String) 

class File(uri : String) extends Resource(uri) { 
    override def toString = "..." 
} 
object File { 
    def apply(uri: String) = new File(uri) 
} 

class Folder(uri : String) extends Resource(uri) { 
    override def toString = "..." 
} 
object Folder { 
    def apply(uri: String) = new Folder(uri) 
} 
+1

Sin embargo, esto duplica la propiedad 'uri' y getter en' File' y 'Folder'. ¿Hay alguna posibilidad de obtener un código limpio que se parece al ejemplo de Java en mi pregunta? –

+0

¿Entonces por qué usa clases de casos? Las clases de casos agregan getter y setters. Escribe clases normales y sus objetos acompañantes. – onof

+0

Porque esto sería demasiado código de la placa de la caldera? ;-) ¿Puedes dar un ejemplo? –

5

hacer que estas dos clases caso se extiende un rasgo común que la definen interfaz y debería funcionar.

Por cierto, necesita un identificador antes de la cláusula de tipo en la declaración case.

trait Resource { 
    val uri: String 
} 

case class File(uri : String) extends Resource 
case class Folder(uri : String) extends Resource 

val arr = Array[Resource](File("test"), Folder("test2")) 

arr.foreach { r : Resource => r match { 
    case s: File => println("It's a file") 
    case s: Folder => println("It's a folder") 
}} 
+1

Esto funciona sin embargo, los métodos de propiedad y getter uri son guardado en ambos 'Archivo' y' Carpeta' (duplicado). Esperaba tener un código limpio como el anterior ejemplo de Java (he actualizado mi pregunta). –

Cuestiones relacionadas