11 votes

constructeurs en scala (primaire/auxiliaire/ primaire par défaut)

Un exercice assez simple de Cay Horstmann livre " Scala pour les impatients " continue à me laisser perplexe. Il s'agit de primary , auxiliary y default primary constructeurs :

ex 5.10 : Considérons la classe

class Employee(val name: String, var salary: Double) {
  def this() { this("John Q. Public", 0.0) }
}

Réécrivez-le pour utiliser des champs explicites et un constructeur primaire par défaut.

Je ne suis pas sûr de ce que je suis censé faire. L'un d'entre vous pourrait-il me proposer une solution ?

Cependant, le fait d'essayer de résoudre cet exercice m'a peut-être fait prendre conscience de quelque chose que je n'avais pas remarqué auparavant à propos du constructeur primaire et de la fonction val (comme vous pouvez le constater, je ne suis pas tout à fait sûr) :

Ai-je raison si je dis qu'un val (comme name en el Employee ci-dessus) ne peut être initialisée que par le biais de la classe primary et non par un constructeur auxiliary un ? Dans ce dernier cas, il serait considéré par le compilateur comme une réaffectation à un fichier de type val causant une erreur.

Au début, je pensais val comme un équivalent approximatif des champs finaux en Java, en espérant qu'il serait légal de les assigner pour la première fois dans n'importe quel constructeur, mais il semble que j'avais tort.

Je ne suis pas tout à fait satisfait de ce qui n'est peut-être qu'une hypothèse, et j'apprécierais que quelqu'un me donne des informations plus précises sur ce point.

14voto

Sergey Passichenko Points 4199

Extrait de "Programming in Scala, 2nd edition" paragraphe 6.7 :

En Scala, chaque constructeur auxiliaire doit invoquer un autre constructeur de la même classe comme L'effet net de cette règle est que chaque invocation de constructeur en Scala finira par appeler le constructeur primaire de la classe. Le constructeur primaire est donc le point d'entrée unique d'une classe.

Ainsi, toutes les données pour l'initialisation de val doit être dans le constructeur primaire.

Votre classe avec des champs explicites peut être quelque chose comme :

class Employee(n: String = "John Q. Public", s: Double = 0.0) {
  val name = n
  var salary = s
}

ou sans valeurs de paramètres par défaut :

class Employee(n: String, s: Double) {
  def this() = this("John Q. Public", 0.0)
  val name = n
  var salary = s
}

12voto

cayhorstmann Points 1274

En fait, ce que j'avais en tête est une version avec un constructeur primaire sans argument, comme ceci :

class Employee {
  private var _name = "John Q. Public"
  var salary = 0.0
  def this(n: String, s: Double) { this(); _name = n; salary = s; }
  def name = _name      
}

Il est clair que cette méthode est inférieure à la définition des champs dans le constructeur primaire, ce qui est le point que je voulais souligner.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X