2015-05-19 18 views
8

Ho una classe astratta con un valore predefinito per il suo parametro. Non voglio dover riutilizzare il valore predefinito nel costruttore di tutte le possibili implementazioni.Parametro di default dell'ereditarietà Scala nella classe genitore

abstract class Place(val place: String = "World") 
class Message(val message: String = "Hello", p: String) extends Place(p) { 
    override def toString = s"$message $place" 
} 

quello che voglio ottenere

new Message("Hi", "Universe") = "Hi Universe" // Ok 
new Message("Hi") = "Hi World" // Doesn't work, second parameter is required 
new Message() = "Hello World" // Doesn't work, second parameter is required 

ho considerato utilizzando un costruttore ausiliario omettendo il secondo parametro, ma non aiuta in quanto non è possibile chiamare i costruttori di super al di fuori del costruttore principale.

Voglio sapere come si fa, o perché non è possibile. Non sto cercando una soluzione alternativa, come non usare l'ereditarietà.

risposta

1

è possibile riutilizzare il valore predefinito in un modo più elegante:

object Place { 
    val defaultPlace = "World" 
} 
abstract class Place(val place: String = Place.defaultPlace) 
class Message(val message: String = "Hello", p: String = Place.defaultPlace) extends Place(p) { 
    override def toString = s"$message $place" 
} 
+0

opere. non come incapsulato. Qui hai 3 oggetti da manipolare (oggetto, astratto e classe). In particolare non dare credito per oggetto e astratto con lo stesso nome. class Message deve conoscere l'oggetto Place, quindi l'utilizzo di questo richiede più cablaggi, se questo ha senso. l'astratto e il concreto dovrebbero gestire tutto. – Drew

3

Ho paura che non sia possibile. Molto semplicemente, stai passando un valore a Place constructor, quindi non userà il default, qualunque sia il suo valore. Se non ti dispiace avere un var invece di una val, qui è una variante che funziona per i vostri 3 casi:

abstract class Place(var place: String = "World") 
class Message(val message: String = "Hello") extends Place() 
{ 
    def this(message: String, place: String) = { 
     this(message) 
     this.place = place 
    } 
    override def toString = s"$message $place" 
} 

costruttori in Scala sono un po 'di un IMHO pasticcio. A volte una soluzione migliore è usare i metodi factory apply() su un oggetto companion, che sono più flessibili.

Problemi correlati