Mis à jour le mardi 7 mars 2017
  • Facile

Ce cours est visible gratuitement en ligne.

Vous pouvez être accompagné et mentoré par un professeur particulier par visioconférence sur ce cours.

J'ai tout compris !

Classes et variables

Connectez-vous ou inscrivez-vous pour bénéficier de toutes les fonctionnalités de ce cours !

Bonjour !

Vous avez donc décidé d'apprendre la programmation avec ce tutoriel. Bonne idée, vous n'allez pas le regretter. :) On commencera en douceur en présentant les possibilités que vous offre le mode interactif de Scala, dont de l'utiliser comme calculatrice.

Nous continuerons en abordant deux concepts clés que la plupart des langages de programmation présentent et sans lesquels ils ne pourraient pas fonctionner (du moins pas correctement) : les variables et leurs types !

Pour finir en beauté (et pour pratiquer, ce qui est la clé de la bonne compréhension d'un langage), vous ferez une série d'exercices qui vous permettront de pratiquer tous les concepts que vous avez vus dans ce chapitre ! :D

Premiers pas

Commencez par ouvrir le mode interactif de Scala comme je vous l'ai montré dans le chapitre précédent. Écrivez un calcul simple, par exemple 1 + 3 (si c'est trop difficile, vous pouvez écrire 1 + 1 :-° ) puis appuyez sur la touche <Entrée>, vous devez avoir ceci à l'écran :

scala> 1 + 3
res0: Int = 4

Déchiffrons le charabia qui s'affiche dans la console :

  • res0 : Scala s'amuse à donner des noms à vos calculs. res0 veut dire résultat n° 0. Si vous faites d'autres calculs, il va les renommer res1, res2, res3 et ainsi de suite.

  • Int : Int est l'abréviation d'Integer, mot anglais qui signifie entier. Les nombres 1, 5, -1 et -14 sont tous des entiers. Pourquoi Scala l'affiche-t-il ? Rassurez-vous, il ne va pas vous donner des cours de maths, il veut juste vous dire que le résultat de 1 + 3 est un entier.

  • 4 : c'est tout simplement le résultat de l'expression 1 + 3.

Donc, en français, la ligne affichée est équivalente à « Votre calcul n° 0 a pour résultat un entier, qui est égal à 4 ».

Félicitations, amis Zéros, vous avez officiellement écrit votre première ligne de code ! ^^

Amusez-vous à faire d'autres tests :

scala> 2 + 5
res1: Int = 7

scala> 5
res2: Int = 5

Un peu de vocabulaire :

  • 1 + 3 est une instruction ou expression.

  • 4 est le résultat d'évaluation de l'expression 1 + 3.

  • Int est le type ou la classe de 4.

  • 1, 3 et 4 sont des objets de type Int ou instances de classe Int.

  • + est un opérateur ou une méthode, tous les objets de même type (ou classe) ont les mêmes opérateurs.

Il y aura forcément beaucoup de nouveaux mots et définitions au début, pensez à les écrire quelque part (sur un bloc-notes, dans votre portable) pour les trouver facilement en cas de besoin.

Il existe d'autres opérateurs sur les Int : -, *, / et %.

  • « - » : différence ;

  • « * » : produit ;

  • « / » : quotient de la division entière ;

  • « % » : reste de la division entière.

Testons ces opérateurs :

scala> 4 * 5
res3: Int = 20

scala> 8 / 3
res4: Int = 2

scala> 8 % 3
res5: Int = 2

Il est très doué en maths, ce Scala ! o_O En plus, il respecte la priorité des opérateurs mathématiques, c'est-à-dire qu'un calcul comme 2 + 5 * 3 retourne 17 (comme en maths) et non pas 21. Si on veut avoir 21, il faudra utiliser des parenthèses : (2 + 5) * 3.

scala> 2 + 5 * 3
res6: Int = 17

scala> (2 + 5) * 3
res7: Int = 21

Si on a des opérateurs de même priorité (« * » et « / », par exemple) l'expression est évaluée de gauche à droite :

scala> 10 / 2 * 5
res8: Int = 25

Un opérateur (méthode) peut être utilisé de 3 manières différentes :

scala> 5 + 3
scala> 5 +(3)
scala> 5 .+(3)

Les trois écritures sont totalement équivalentes, il y a des cas de figure où l'on préfère une d'entre elles aux autres mais on va discuter ce sujet une fois qu'on aura un peu avancé dans le cours.

Les nombres à virgule (ou décimaux)

Ce sont les nombres comme 5,3 et -8,7777 (sauf qu'on utilise le point à la place de la virgule). Leur utilisation est pareille à celle des entiers :

scala> 5.3
res0: Double = 5.3

Le Int d'avant a été remplacé par Double, qui désigne un nombre à virgule. Donc, en termes de programmeur, l'objet 5.3 est de classe (ou type) Double.
On peut entre autres utiliser les opérateurs (méthodes) + (addition), - (soustraction), * (multiplication) et / (division) :

scala> 1.0 - 5.5
res1: Double = -4.5

scala> 5847.3525 * 14.12
res2: Double = 82564.6173

On peut même mélanger des entiers et des décimaux dans une même expression (instruction, opération), le résultat sera un décimal :

scala> 8.2 / 2
res3: Double = 4.1

Les caractères

Ils sont des lettres, chiffres ou symboles mis entre apostrophes :

scala> 'a'
res0: Char = a

scala> 'Z'
res1: Char = Z

'a' et 'Z' sont donc deux objets de classe (ou type) Char.

Tout caractère est équivalent à un nombre appelé code ASCII du caractère (prononcez code « Aski »). Par exemple, le code ASCII de 'A' est 65, celui de 'B' est 66, celui de 'C' est 67, etc.
Pour connaître le code ASCII d'un caractère, il suffit d'utiliser l'opérateur (ou méthode) toInt :

scala> 'B' toInt
res2: Int = 66

Les chaines de caractères

Il s'agit de bouts de texte entourés par des guillemets :

scala> "Bienvenue sur le SDZ !"
res0: java.lang.String = "Bienvenue sur le SDZ !"

La classe (ou type) des chaines est java.lang.String, ce nom est trop long, donc on va dire seulement String.
On peut « rassembler » des chaines en utilisant l'opérateur « + », on appelle ceci une concaténation.

scala> "Salut, " + "les zéros !"
res1: java.lang.String = "Salut, les zéros !"

La méthode (opérateur) « concat » a le même effet que « + » :

scala> "Salut, " concat "les zéros !"
res2: java.lang.String = "Salut, les zéros !"

scala> "Salut, ".concat("les zéros")
res3: java.lang.String = "Salut, les zéros"

On peut accéder à un caractère de la chaine en mettant sa position entre des parenthèses.

scala> "Hello"(0)
res4: Char = H

scala> "Hello"(2)
res4: Char = l

Voici quelques autres méthodes (ou opérateurs) :

Méthode

Rôle

Exemple

Résultat

charAt

même effet que les parenthèses

"Je programme" charAt 1

e

*

répète la chaine autant de fois que l'entier donné

"SDZ " * 2

SDZ SDZ

length

retourne la longueur de la chaine

"Une chaine" length

10

scala> "SDZ " * 2
res5: String = "SDZ SDZ "

scala> "SDZ ".length
res6: Int = 4

Les booléens

Le type booléen est un peu spécial car il ne peut prendre que deux valeurs : VRAI et FAUX, qui sont représentées en Scala par true et false (simple traduction en anglais).

scala> true
res0: Boolean = true

scala> false
res1: Boolean = false

Comme vous pouvez le voir, la classe de true et false en Scala est Boolean.
Les opérateurs (méthodes) sur les booléens sont NON, ET et OU :

  • ET : a ET b est VRAI si a et b valent VRAI. Il est FAUX dès que l'un des deux opérandes est FAUX.

  • OU : a OU b est VRAI si a est VRAI ou si b est VRAI (ou les deux à la fois). Il ne donne FAUX que lorsque les deux opérandes sont FAUX.

  • NON : NON a vaut VRAI si a vaut FAUX et vice versa.

Avec a et b chacun est soit VRAI soit FAUX.
Les tableaux suivants traitent tous les cas possibles :

a

NON a

VRAI

FAUX

FAUX

VRAI

a

b

a ET b

VRAI

VRAI

VRAI

VRAI

FAUX

FAUX

FAUX

VRAI

FAUX

FAUX

FAUX

FAUX

a

b

a OU b

VRAI

VRAI

VRAI

VRAI

FAUX

VRAI

FAUX

VRAI

VRAI

FAUX

FAUX

FAUX

En Scala, NON est représenté par « ! », ET par « && » et OU par « || » (le caractère « || » n'est pas deux « L » minuscule collés : ce sont deux caractères pipe (prononcer « païpe »)), voici quelques exemples :

scala> !false
res2: Boolean = true

scala> true && false
res3: Boolean = false

scala> true || false
res4: Boolean = true

Et à quoi sert ce type ?

Il est particulièrement utile lorsqu'on fait des comparaisons entre les nombres, par exemple, la méthode « < » vérifie si le premier nombre est strictement inférieur au deuxième ou non :

scala> 2 < 5
res5: Boolean = true

scala> 2.2 < 2
res6: Boolean = false

La valeur de l'expression a < b est toujours soit true soit false. Remarquez qu'on peut comparer deux nombres de classes différentes (Int et Double).
Voici la liste des opérateurs de comparaison :

Opérateur

Rôle

Exemple

Résultat

==

égalité

5 == -(-5)

VRAI

!=

non-égalité

5 != -(-5)

FAUX

<

inférieur strictement

2 < 2

FAUX

<=

inférieur ou égal

2 <= 2

VRAI

>

supérieur strictement

4 > 2

VRAI

>=

supérieur ou égal

8 >= 7

VRAI

Deux instances (objets) de la même classe (même ceux qui ne sont pas des nombres) peuvent être comparés avec les méthodes (ou opérateurs) « == » et « != ». Les instances de Char sont égales à leur code ASCII.
Quelques tests :

scala> 5 == 5
res7: Boolean = true

scala> -3 > -3
res8: Boolean = false

scala> "Bonjour" == "Good Morning"
res9: Boolean = false

scala> 'A' == 65
res10: Boolean = true

Les objets de type Boolean sont utiles dès que l'on veut faire des conditions (ou structures conditionnelles). Une structure conditionnelle s'écrit (en français) de cette manière :

Si (CONDITION) EXPRESSION1 Sinon EXPRESSION2

J'explique :
CONDITION est une instance de la classe Boolean, elle est soit VRAI soit FAUX.

  • Si CONDITION vaut VRAI alors c'est EXPRESSION1 qui est évaluée ;

  • Si CONDITION vaut FAUX alors c'est EXPRESSION2 qui est évaluée.

Vous allez mieux comprendre avec des exemples :

Si (VRAI) 2 Sinon 3

Si (0 > 1) "Bonjour" Sinon "Bonsoir"

Si (1 + 5 == 6) VRAI sinon FAUX

Quel est le résultat de chaque expression ?

Pour la première, on a CONDITION == VRAI donc la valeur de l'expression est 2.
Pour la 2e, 0 > 5 vaut FAUX donc la valeur de l'expression est « Bonsoir ».
Pour la 3e, 1 + 5 == 6 vaut VRAI donc toute l'expression vaut VRAI.

J'espère que c'est clair. Passons à la syntaxe des conditions en Scala :

if (CONDITION) EXPRESSION1 else EXPRESSION2

Il suffit de remplacer Si par if et Sinon par else (simple traduction en anglais). Voici les exemples précédents traduits :

scala> if (true) 2 else 3
res11: Int = 2

scala> if (0 > 1) "Bonjour" else "Bonsoir"
res12: java.lang.String = "Bonsoir"

scala> if (1 + 5 == 6) true else false
res13: Boolean = true

Les variables

Lorsque l'on programme, on est souvent amené à utiliser des objets. Par exemple, si on doit calculer plusieurs fois la circonférence d'un cercle, on aura certainement besoin d'utiliser le nombre pi plus d'une fois.

Le fait qu'on doive taper la valeur de pi plusieurs fois dans la console est fastidieux et on prend le risque de faire une faute de frappe (2e utilisation) :

scala> 2 * 3.141592653 * 3
res0: Double = 18.849555918

scala> 2 * 31.41592653 * 0.2
res1: Double = 12.566370612

La solution est de sauvegarder la valeur de pi dans une variable.

C'est quoi une variable ?

C'est une boîte dans laquelle on peut mettre n'importe quel objet (1, true, 'c', "Shopping").
On crée une variable de la manière suivante (on dit aussi qu'on déclare la variable) :

var <Nom>: <Classe> = <ValeurInitiale>
  • var : c'est un mot-clé du langage. Un mot-clé sert à annoncer quelque chose d'important à Scala ou de lui dire de faire un certain traitement. Ici, var prévient Scala qu'on va créer une variable. D'ailleurs, on a déjà utilisé d'autres mots-clés : if et else qui annoncent au programme qu'on est en train d'utiliser une structure conditionnelle.

  • <Nom> : c'est le nom qu'on veut donner à notre variable (par exemple pi, x, rectangle).

  • <Classe> : c'est la classe de la variable (Int, Boolean, String...). On ne pourra mettre dans la variable que des objets de cette même classe.

  • <Valeur Initiale> : c'est n'importe quel objet ou autre variable dont la classe est <Classe>. On dit qu'on initialise la variable.

Créons notre variable qui va contenir la valeur (approchée) de pi :

scala> var pi: Double = 3.141592653
pi: Double = 3.141592653

On commence par le mot var suivi par le nom de la variable : pi. On a besoin d'une variable qui contiendra un nombre décimal (3.1415...), qui est une instance (un objet) de la classe Double, donc il faut que pi soit aussi de cette classe. Enfin, on initialise pi à 3.141592653. Scala réaffiche votre ligne (sans le var) pour vous dire que tout est bien passé.

Pour utiliser la variable, il suffit d'écrire son nom. Ce dernier sera remplacé par la valeur qu'on a mise dans notre boîte magique:

scala> pi
res2: Double = 3.141592653

On peut même faire des opérations avec (c'était notre but dès le début, calculer la circonférence d'un cercle) :

scala> 2 * pi * 3
res3: Double = 18.849555918

scala> 2 * pi * 5
res4: Double = 31.41592653

Vous avez compris ? :D

Nomenclature des variables

On ne peut pas nommer une variable n'importe comment, il y a bien des règles à suivre, le nom :

  • peut contenir des lettres, des chiffres et des symboles mais pas un caractère blanc (espace, retour chariot) ;

  • ne peut pas commencer par un chiffre ;

  • ne doit pas contenir des parenthèses, accolades, crochets, points, virgules, points-virgules, apostrophes ou guillemets ;

  • doit être différent des mots-clés du langage (vous pouvez consulter la liste complète en annexe).

Ainsi les noms 123, J'aime et Bi{ ne sont pas valides. Par contre, bonjour, Zéro et !!+*%? sont corrects.
Les programmeurs Scala (oui oui, ça vous concerne ;) ) ont tendance à ne jamais nommer des variables qui commencent par une lettre majuscule. Pour les noms qui sont composés de plusieurs mots (par exemple « valeur de pi ») on préfère la camelCase (valeurDePi) et non pas la séparation_des_mots_par_des_underscores (valeur_de_pi).

Affectation

On a souvent besoin de changer les valeurs des variables déjà déclarées (créées). Par exemple, une variable qui sert à enregistrer la température doit changer régulièrement. Comment faire ? C'est simple, il suffit d'écrire le nom de la variable suivi du signe « = » et d'un objet ayant la même classe que cette variable, on dit qu'on affecte un nouvel objet à la variable. L'initialisation est une affectation au moment de la création.

scala> var x: Int = 0
x: Int = 0

scala> x = 5
x: Int = 5

scala> x
res5: Int = 5

On a parfois des variables dont on ne désire pas changer la valeur, par exemple pi, qui est une constante universelle. Vous allez me dire qu'il suffit de ne pas lui affecter une autre valeur ! C'est vrai, mais ce n'est pas aussi évident. Il suffit qu'on change sa valeur par erreur et puis, ka boom, le programme ne fonctionnera plus (j'ai ici écrit « = » à la place de « * », par erreur :-° ) :

scala> pi = 2 * 3.2
pi: Double = 6.4

Alors, que faire ?

On doit déclarer la variable comme constante (ou une valeur). C'est simple, il suffit de remplacer le mot-clé var par val :

scala> val pi: Double = 3.141592653

Désormais, dès que quelqu'un tente de changer pi (par erreur aussi :-° ), il y aura une belle erreur :

scala> val pi: Double = 3.141592653
pi: Double = 3.141592653

scala> pi = 2 * 3 
<console>:6: error: reassignement to val
       pi = 2 * 3
          ^

Il y a eu une erreur, « reassignement to val » veut dire « réaffectation à une val ». Le caractère « ^ » pointe vers l'endroit où l'erreur à été repérée, à savoir le signe égal de l'affectation.
On peut cependant utiliser une variable constante (ou objet constant) dans des expressions :

scala> pi
pi: Double = 3.141592653

scala> 2 * pi * 3
res6: Double = 18.849555918

On a tendance en Scala à appeler les variables déclarées avec var des vars (ou variables mutables) et celles avec val des vals (ou variables non mutables).

res0, res1, res2...

Tous les resX affichés dans la console ne sont pas des noms simples, remarquez la ressemblance entre les deux résultats affichés dans ces deux cas :

scala> val p: Int = 2 * 4
p: Int = 8

scala> 2 * 4
res7: Int = 8

En effet, lorsque vous n'affectez votre expression (calcul, concaténation de chaines, structure if-else...) à aucune variable, Scala crée une variable non mutable (val) nommée resX (où X est un nombre) et l'initialise au résultat retourné par votre expression. On peut bien sûr utiliser ces resX comme toute autre val :

scala> res0 * res7 - res1
res8: Double = 138.230076732

C'est bon ? Vous avez tout assimilé ? Essayez donc de faire les exercices. :-°

Exercices

La meilleure façon d'apprendre un langage (surtout si c'est votre premier langage) est de le pratiquer le plus possible. Ceci est le but des exercices et des TP (travaux pratiques) que vous rencontrerez tout au long de ce tutoriel. Il ne faut pas aller directement à l'indication ou à la solution, cela ne vous aidera pas à avancer. Prenez tout votre temps, faites des essais, lisez l'indication, refaites d'autres essais et enfin lisez la solution. S'il y a quelque chose que vous n'avez pas bien assimilé (le cours, la correction des exercices ou même la raison pour laquelle votre solution ne marchait pas) vous pouvez toujours poser vos questions sur le forum (il faut lire les règles du forum avant de poster :pirate: ).

Exercice 1

Calculez avec l'interpréteur Scala les expressions suivantes :

  • 8 + 3 ;

  • 1 + 7 * 2 ;

  • (1 + 7) * 2 ;

  • (12 % 3) * (5 / 2).

Indications

o_O

Solution
scala> 8 + 3
res0: Int = 11

scala> 1 + 7 * 2
res1: Int = 15

scala> (1 + 7) * 2
res2: Int = 16

scala> (12 % 3) * (5 / 2)
res3: Int = 0

Exercice 2

Énoncé

Quelle est la classe (type) de 'a', 'b', et 'z' ? Affichez leur code ASCII.

Indications

Utilisez la méthode (opérateur) toInt.

Solution

Ce sont des caractères, leur classe est Char.

scala> 'a' toInt
res0: Int = 97

scala> 'b'.toInt
res1: Int = 98

scala> 'z' toInt
res2: Int = 122

Exercice 3

Énoncé

Essayez de comparer deux caractères (par exemple 'A' et 'B') avec « < » ou « > ». Que remarquez-vous ?

Indications

Revenez voir ce qu'il se passe lorsqu'on utilise « == » sur deux objets de classe Char.

Solution

On peut comparer deux chars, ce sont leurs codes ASCII qui sont comparés.

Exercice 4

Énoncé
  • Quel est le type (la classe) de 1.0 ?

  • Qu'est-ce qui se passe si on fait la somme d'un objet de cette classe et d'un autre de classe Int ?

Indications

Testez !

Solution

La classe est Double.

scala> 1.0 + 5
res0: Double = 6.0

Lorsque on mélange des entiers avec des décimaux dans une même expression (opération, calcul) le résultat est un Double.

Exercice 5

Énoncé
  • Quel est le nom complet de la classe String ?

  • Que veut dire le mot concaténer ?

  • Quelle est la classe de l'objet retourné par la concaténation d'un String avec un Int ou Double ?

  • Quel est le résultat de multiplication d'un objet String par un entier ? Peut-on multiplier un String par un Double ?

Indications

Regardez le cours pour les définitions et faites des tests pour les autres questions.

Solution

La classe des chaines est java.lang.String.
Concaténer deux String veut dire les coller ensemble.
La concaténation d'un String avec n'importe quel autre objet retourne un String.

scala> "123 " * 3
res0: String = "123 123 123 "

La multiplication d'un objet String par un Int retourne le String répété autant de fois que l'entier en question. On ne peut pas multiplier un String par un objet de classe Double.

Exercice 6

Énoncé

Évaluez les expressions suivantes :

  • (true || false) && true ;

  • true || (false && true) ;

  • (true && false) && true ;

  • 5 == 2 + 3 ;

  • 'A' < 23 ;

  • "123456789" == "123456879".

Indications

:o

Solution
scala> (true || false) && true
res0: Boolean = true

scala> true || (false && true)
res1: Boolean = true

scala> (true && false) && true
res2: Boolean = false

scala> 5 == 2 + 3
res3: Boolean = true

scala> 'A' < 23
res4: Boolean = false

scala> "123456789" == "123456879"
res5: Boolean = false

Dans l'exemple 5 on compare le code ASCII de 'A' (65) avec 23.
Dans l'exemple 6, 7 et 8 sont inversés dans la deuxième chaine.

Exercice 7

Énoncé
  • Avec quel mot-clé crée-t-on une variable ?

  • Créez une variable mutable m de classe Double initialisée à 5.32.

  • Créez une variable non mutable nm de classe Char initialisée à '@'.

Indications

Un petit coup d'œil sur la sous-partie des variables ne vous fera pas de mal. ;)

Solution

C'est une question piège ! Il y a deux mots-clés : val et var.

scala> var m: Double = 5.32
m: Double = 5.32

scala> val nm: Char = '@'
nm: Char = @

Exercice 8

Énoncé
  • Créez une variable n de classe Int initialisée à une valeur quelconque (de votre choix).

  • Écrivez une expression qui affiche « Bonjour, le monde. » sur une seule ligne si x est négatif et sur deux lignes (retour à la ligne après la virgule) si x est positif ou nul.

Indications
  • Pensez à un if-else pour la condition.

  • Le caractère ' ' produit un retour à la ligne (oui, il est considéré comme un seul caractère).

Solution
scala> val x: Int = 8
x: Int = 8

scala> if (x < 0) "Bonjour, le monde." else "Bonjour,\nle monde."
res0: java.lang.String =
"Bonjour,
le monde."

Exercice 9

Énoncé
  • Définir le mot affectation (dans son sens informatique).

  • Une initialisation est-elle une affectation ?

Indications

Fouillez le cours. :p

Solution
  • Une affectation est une association d'un objet à une variable.

  • Oui. L'initialisation est une affectation au moment de la création.

Ouah ! On en a appris des choses, maintenant ! Surtout, si vous n'avez pas compris quelque chose, n'hésitez pas à relire : mieux vous aurez compris ces concepts et mieux vous comprendrez les concepts que nous apprendrons dans les autres chapitres ! :)

Bonne continuation et rendez-vous dans le chapitre suivant ! ;)

Exemple de certificat de réussite
Exemple de certificat de réussite