2010-09-25 11 views
3

Ma question est que s'il est possible de surcharger les constructeurs en scala?Est-il possible de surcharger les constructeurs en scala?

Je peux donc écrire du code comme:

var = new Foo(1) 
var = new Foo("bar") 

Et s'il est impossible, y at-il des astuces équivalent?

+0

Vous parlez de constructeurs, pas d'initialiseurs de classe. Veuillez changer le libellé de votre question Les initiateurs de classe sont exécutés lorsque la classe est chargée, tandis que les constructeurs sont appelés lorsque des instances de la classe sont créées. –

+0

duplication possible de [Scala constructor overload?] (Http://stackoverflow.com/questions/1095329/scala-constructor-overload) –

Répondre

9

Bien sûr, mais il existe des restrictions. Scala exige que l'un de vos constructeurs soit "primaire". Le constructeur principal a la syntaxe spéciale et pratique de mettre les arguments du constructeur juste après le nom de la classe. D'autres constructeurs "secondaires" peuvent également être définis, mais ils doivent appeler le constructeur primaire. C'est différent de Java, et un peu plus restrictif. C'est fait de cette façon pour que les arguments constructeurs puissent être traités comme des champs.

Votre exemple ressemblerait

class Foo(myArg:String){ //primary constructor 
    def this(myIntArg:Int) = this(myIntArg.toString) //secondary constructor 
} 

val x = new Foo(1) 
val y = new Foo("bar") 
+0

Merci, j'ai raté la partie 'constructeur auxiliaire' dans' Programming in Scala'. –

5

Comme vous pouvez le voir dans l'exemple de Dave Griffith, le constructeur principal doit être le « plus général » un dans le sens que tout autre constructeur doit appeler (directement et indirectement). Comme vous pouvez l'imaginer, cela conduit parfois à des constructeurs primaires laids. Une stratégie commune est d'utiliser l'objet compagnon pour cacher la laideur (et vous n'avez pas besoin de taper la « nouvelle »):

class Foo private (arg:Either[String, Int]){ 
    ... 
} 

object Foo { 
    def apply(arg:String) = new Foo(Left(arg)) 
    def apply(arg:Int) = new Foo(Right(arg)) 
} 

val a = Foo(42) 
val b = Foo("answer") 

Bien sûr, vous devez être prudent si vous voulez hériter de votre classe (par exemple, ce n'est pas possible dans l'exemple ci-dessus)

+0

c'est mieux que les constructeurs auxiliaires. car les constructeurs aux ne peuvent effectuer que des conversions de champs simples, mais apply() peut faire beaucoup dans la logique du code pour normaliser des entrées complètement différentes. – linehrr

0
class MyCons{  

    def this(msg:String){  
     this()  
     println(msg) 
    }  

    def this(msg1:String , msg2:String){  
     this()  
     println(msg1 +" "+msg2)  
    }  

} 

pour d'autres constructeur auxiliaire nous devons avoir besoin d'appeler le constructeur primaire ou autre auxiliaire définis précédemment.

+0

Avec des questions aussi vieilles que celle-ci, il est utile que vous expliquiez en quoi votre réponse diffère des réponses déjà fournies. – jwvh

Questions connexes