Il y a 15 ans -
Temps de lecture 4 minutes
Les constructeurs et méthodes en Scala
Dans le billet précédent, nous avons vu une partie de la syntaxe de Scala ainsi que le mécanisme d’inférence. Dans ce deuxième billet, nous allons aller plus loin et étudier la déclaration des constructeurs et des méthodes en Scala.
Les constructeurs
Tous les pratiquants du langage Java savent que celui-ci possède des constructeurs que l’on peut expliciter sous forme de méthodes spéciales :
public class Vehicle { public String name; public int price; public Vehicle(String name, int price) { this.name = name; this.price = price; } } Vehicle car = new Vehicle("Ferrari", 10);
En Scala, toutes les classes ont aussi au moins un constructeur, mais la déclaration de celui-ci est un peu différente de celle en Java :
class vehicle(name: String, price:Int) { } var car = new vehicle("Ferrari", 100000);
Ce qui nous saute aux yeux est le fait que le constructeur n’est pas une méthode spéciale : celui-ci est défini par le corps de la classe.
Par ailleurs, si vous avez l’habitude de programmer en Java, vous devez sans doute vous demander comment est-il possible de surcharger le constructeur ?
class vehicle(name: String, price:Int) { def this(name: String) = { this(name, 10) } } val car = new vehicle("Lamborghini")
La classe vehicle a maintenant deux constructeurs, un prenant une String et un Int et le second prenant une String. L’inconvénient majeur est que les constructeurs surchargés doivent faire appel au constructeur par défaut (celui du corps de la classe précédemment défini). C’est une contrainte qu’il faut prendre en compte lors de la conception de la classe.
Une autre notion clé des constructeurs en Scala se situe au niveau des paramètres. Les paramètres du constructeur de la classe vehicle ne sont pas des variables, mais des valeurs dans le sens où celles-ci ne peuvent être réassignées. Néanmoins, il est possible de les définir en tant que variables:
class vehicle(name: String, var price:Int) { def buy() = { price = price + 1000 } }
Dans cet exemple, la fonction buy() ajoute une taxe au prix d’un véhicule. La variable price peut être réassignée, car dans les paramètres du constructeur le mot clé var a été utilisé. Ce dernier permet de définir une variable public. Au passage, en Scala les éléments sont public par défaut.
Ainsi, il est possible d’écrire le code suivant:
class vehicle(name: String, var price:Int) val car = new vehicle("Lamborghini", 100000) car.price = 150000
En Java nous aurions:
public class Vehicle { private String name; private int price; public Vehicle(String name, int price) { this.name = name; this.price = price; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getPrice() { return price; } public void setPrice(int price) { this.price = price; } } Vehicle vehicle = new Vehicle("Lamborghini", 100000); vehicle.setPrice(150000);
Le volume de code saute aux yeux !
Les méthodes
En Scala la définition d’une méthode se fait de la manière suivante :
def name() = { price = price + 1000 }
Le mot clé def permet de définir une méthode.
Tout comme en Java, Scala permet de définir des niveaux de visibilité :
def buy() = { //méthode public price = price + 1000 } private def send() = { //méthode private println("send a car") } protected def parkByDate() = { //méthode protected import java.util._ new Date }
Ici on remarquera la déclaration d’import dans une méthode. Cela signifie que seulement dans la méthode parkByDate() , il est possible d’accéder à tous les membres de java.util. Au passage, en Scala le caractère _ dans la déclaration de l’import est équivalent au caractère * en Java, car ce dernier a une autre utilité que nous verrons plus tard.
Une autre différence concerne protected. Par défaut, celui-ci s’applique uniquement aux sous-classes et non aux autres classes du package (ie Java). Cependant, il est possible de pallier à ce problème de la manière suivante:
protected[xebia] def parkByDate() = { import java.util._ new Date }
Dans cet exemple, la méthode parkByDate() peut être appelée par la classe dans laquelle celle-ci se trouve, mais aussi par toute autre classe du package xebia. Ce système peut aussi être appliqué pour les méthodes private (équivalent aux package private Java).
Enfin dernier point, vous aurez remarqué que les méthodes ne possèdent pas de type de retour et/ou de return. Le mécanisme d’inférence fait effet ici aussi. Bien entendu, il est possible d’expliciter un return:
def buy():Int = { price = price + 1000 return price }
A travers ce billet, nous avons pu voir que Scala permet d’adopter une programmation orientée objet. Ces exemples nous montrent que Scala est moins verbeux et reste un langage lisible. Ajouter une propriété revient à ajouter un paramètre au constructeur, tandis qu’en Java il faut ajouter une variable privée, les getter et setter et modifier le constructeur avec une initialisation dans celui-ci.
Référence :
Commentaire
2 réponses pour " Les constructeurs et méthodes en Scala "
Published by Fabien , Il y a 15 ans
En java, le fait de mettre un getter et un setter pour les variables d’instance est tout sauf une obligation, mais seulement une bonne pratique de codage.
Rien n’empêche donc en java d’avoir sensiblement la même longueur de code qu’en Scala, en rendant public les variables d’instance.
C’est d’ailleurs le cas dans votre tout premier exemple de cet article.
Pour ce qui est de la lisibilité, à mon sens, java est de loin beaucoup plus lisible. Le fait de considérer implicitement que les paramètres passés au constructeur sont des variables d’instance par exemple ne me parait pas très naturel, ni forcément toujours le cas : on peut par exemple se servir d’un paramètre dans le constructeur sans pour autant le stocker en variable d’instance.
PS: Malgré mes remarques, sachez que je suis un fervent lecteur de votre blog et en apprécie la qualité !
Published by parnas , Il y a 13 ans
Violer l’encapsulation n’est pas à priori un gage de qualité. Se contenter de compter le nombre de lignes n’est pas non plus un gage de qualité sinon nombre de langages se seraient imposés depuis longtemps.