Sei sulla pagina 1di 25

Les CLASSES

J AVA S C R I P T (Programmation Internet) V O L . I I I

J.B. Dadet DIASOLUKA Luyalu Nzoyifuanga


+243 - 851278216 - 899508675 - 991239212 - 902263541 - 813572818
La dernière révision de ce texte est disponible sur CD.

Les « CLASSES » en JavaScript :

Un [pseudo] type particulier en JavaScript, c’est la « class » (à ne pas


confondre avec l’attribut « class » des balises HTML).

Les « classes » permettent et facilitent l’usage de « méthodes sta-


tiques ».

<script type="text/javascript"> "use strict";


class O {
static auj() {return Date()};
}

let i = new O();


console.log("O.auj = ",O.auj());

// console.log("i.auj = ",i.auj());
// TypeError: i.auj is not a function
</script>

Une autre illustration avec le pseudo-type « class » :

<script type="text/javascript"> "use strict";


class Quad {
static quad(n) {
n = n || 1;
// Si n== 0 ou indéfini, alors = 1.
return n * 4;
Les CLASSES en JavaScript

}
}

// A accès à (ou extension de) Quad ci-haut


class DbleQuad extends Quad {
static quad(n) {
return super.quad(n) * super.quad(n);
// Le quad de Quad ci-haut, pas
// celui juste ci-dessus.
}
}

console.log(Quad.quad()); // 4
console.log(Quad.quad(5)); // 20
// quad() de la class Quad

console.log(DbleQuad.quad(3)); // 144
// quad() de la classe DbleQuad
</script>

CHAPITRE 6 : Quelques notions importantes à savoir :

I. Classes en JavaScript :

Contrairement aux langages C/C++, JS ne possède pas les types de don-


nées enum, structure...., et même les objets en JS ne sont pas des
classes comme dans C++. https://www.ecma-international.org/ecma-262/5.1

ECMAScript is object-based: basic language and host facilities are provided by objects,
and an ECMAScript program is a cluster of communicating objects. An ECMAScript
object is a collection of properties each with zero or more attributes that determine
how each property can be used—for example, when the Writable attribute for a proper-
ty is set to false, any attempt by executed ECMAScript code to change the value of the
property fails. Properties are containers that hold other objects, primitive values, or
functions. A primitive value is a member of one of the following built-in types: Unde-
fined, Null, Boolean, Number, and String; an object is a member of the remaining
built-in type Object; and a function is a callable object. A function that is associated
with an object via a property is a method.

J.D.B. DIASOLUKA Nz. Luyalu 2 / 25 JavaScript Tome-III


Les CLASSES en JavaScript

ECMAScript defines a collection of built-in objects that round out the definition of
ECMAScript entities. These built-in objects include the global object, the Object ob-
ject, the Function object, the Array object, the String object, the Boolean object, the
Number object, the Math object, the Date object, the RegExp object, the JSON ob-
ject, and the Error objects Error, EvalError, RangeError, ReferenceError, Syn-
taxError, TypeError and URIError.

JS est un langage de programmation orienté objet (OOP) dans lequel


TOUT sauf les valeurs primitives est objet (c’est-à-dire nativement
doté ou pouvant à tout moment être doté de membres [ intrin-
sèques ] : propriétés représentant des valeurs et méthodes = fonc-
tions). Un membre particulier ou propriété particulière des objets JS
c’est le prototype qui est une propriété au sens OOP figurant une
bibliothèque des propriétés héritables de l’objet en cours. Dans cer-
tains langages de programmation les membres des objets complexes
(appelons ces objets « structures ») sont aussi appelés « attributs ».
Techniquement, en JavaScript « attribut » réfère à une caractéris-
tique particulière d’une propriété (attribute : internal value that de-
fines some characteristic of a property - https:/www.ecma-
international.org/ecma-262/8.0).

Mais qui a dit que syntactiquement en JS les classes au look C++,


Smalltalk, ou Java (ou class-iques dit-on) n’existent pas, seuls les
objets et leurs prototypes ? Depuis le standard ECMAScript 2015
Language Specification – ECMA-262 6th Edition, JS dispose d’une
syntaxe spéciale « class » permettant de plus facilement créer des
objets et manipuler leurs prototypes et donc l’héritage.

En fait, class en JS est simplement une syntaxe spéciale pour définir


d’un coup un constructeur et les méthodes (pas les propriétés) de son
prototype. En réalité une class JS n’est ni plus ni moins une fonc-
tion : il n’existe pas d’entité spécifique class en JavaScript.

<script type="text/javascript"> "use strict";


let notreClass = class nomClasse {}
console.log(notreClass)
// function nomClasse() [FIREFOX]
J.D.B. DIASOLUKA Nz. Luyalu 3 / 25 JavaScript Tome-III
Les CLASSES en JavaScript

// class nomClasse {} [YANDEX]


console.log(typeof notreClass) // function
</script>

On introduit une définition de classe avec le mot clé « class », et le


constructeur d’une classe ne peut jamais être appelé sans « new ».
Par défaut, le constructeur d’une classe est une fonction vide.

Version class, sans prototype explicitement défini :

<script type="text/javascript"> "use strict";


class Person {
constructor(id) { this.id = id; }

congrat() {
console.log("Hello,",this.id);
// Hello, Brejnev.
}
}

let president = new Person("Brejnev.");


president.congrat();
</script>

Version objet : il faut définir explicitement le prototype.

<script type="text/javascript"> "use strict";


function Person(id) { this.id = id; }

Person.prototype.congrat = function() {
console.log("Hello,",this.id);
}

let president = new Person("Brejnev.");


// president hérite de la méthode congrat
// via le prototype.
president.congrat(); // Hello, Brejnev.
</script>

En fait, l’identifiant de la classe est aussi la fonction constructeur.

J.D.B. DIASOLUKA Nz. Luyalu 4 / 25 JavaScript Tome-III


Les CLASSES en JavaScript

<script type="text/javascript"> "use strict";


var vClass = class ClassName {
constructor(p) {
this.id=p;
};
fct(){console.log("Hello")}
}
console.log(vClass === vClass.prototype.constructor);
// true
console.log(
Object.getOwnPropertyNames(vClass.prototype));
// Array [ "constructor" , "fct" ]
</script>

Une classe JS possède, en plus des propriétés et méthodes comme


dans les objets, un constructeur.

Quelques différences entre « classe » et « objet » :

Programme avec « objet » :

<script type="text/javascript"> "use strict";


function Candidat (p1 = "Kombo", p2 = "00000"){
this.name = p1;
this.matr = p2;

this.msg = function () {
console.log(`Objet: Nom= ${this.name}`,
`Matr=${this.matr}`);
}

let n = new Candidat(undefined,2018);


console.log(n);
n.msg();
</script>

J.D.B. DIASOLUKA Nz. Luyalu 5 / 25 JavaScript Tome-III


Les CLASSES en JavaScript

Le même petit programme avec cette fois-ci une « classe » :

<script type="text/javascript"> "use strict";


class Candidat {
constructor(p1 = "Kombo", p2 = "00000") {
this.name = p1;
this.matr = p2;
}

msg() {
console.log(`class: Nom= ${this.name}`,
`Matr=${this.matr}`);
}
}

let n = new Candidat(undefined,2018);


console.log(n);
n.msg();
</script>

Une des différences frappantes c’est que « Objet » reprend la fonc-


tion « msg » parmi ses propriétés (plutôt méthodes) propres listées,
alors que « class » le reprend dans son prototype, mais évidemment
les deux l’exécutent.

J.D.B. DIASOLUKA Nz. Luyalu 6 / 25 JavaScript Tome-III


Les CLASSES en JavaScript

Comme on le voit ci-haut, une classe JS possède un constructeur, en


plus des propriétés et méthodes comme tous les autres objets.

Un exemple de l’utilisation de « class » en JavaScript :

<script type="text/javascript"> "use strict";


class Polygon {
constructor(height, ...widths) {
this.name = 'Polygon';
this.height = height;
this.width = widths[1];
}
surf(){return this.height*this.width};
}

J.D.B. DIASOLUKA Nz. Luyalu 7 / 25 JavaScript Tome-III


Les CLASSES en JavaScript

class Rect extends Polygon {


constructor(length,width) {

super(length, null, width||length);


// this.length = length;
// Définition explicite de « this.length »
// Sans cette définition, « this.length »
// restera « undefined » comme ici.

if(!width) this.name = 'Square';


else this.name = 'Rectan';
}
}

console.log(
new Rect(3,4).name, // Rect
new Rect(3,4).length, // undefined
new Rect(3,4).width, // 4
new Rect(3,4).height, // 3
new Rect(3,4).surf(), // 12
);

console.log(
new Rect(5).name, // Rect
new Rect(5).length, // undefined
new Rect(5).width, // 5
new Rect(5).height, // 5
new Rect(5).surf(), // 25
);
</script>

Les corps des classes utilisent automatiquement le mode strict, le


corps des classes (pour les expressions et les déclarations de classes)
est exécuté en mode strict (càd que la méthode constructeur, les mé-
thodes statiques, le prototype, les accesseurs [getters] et les muta-
teurs [setters] sont exécutés en mode strict).

Un peu plus de détails sur les « class » en JavaScript.

J.D.B. DIASOLUKA Nz. Luyalu 8 / 25 JavaScript Tome-III


Les CLASSES en JavaScript

Les fonctions liées aux classes sont exécutées en mode strict quel
que soit le mode de JS.

Un « constructor » permet de créer et d'initialiser les objets. Lors de


la création d’un objet, l’objet lui-même est son propre constructeur.
Le constructeur d’une classe est explicite et doit être unique.

<script type="text/javascript"> "use strict";


class imc {
constructor(pds,tHt) {
this.icorp = pds / Math.pow(tHt,2);
}
}
let dias=new imc(60,1.65)
console.log(dias.icorp.toFixed(2),"kg/m2");
// 22.04 kg/m2
</script>

Exemple 2 : On peut utiliser une expression de classe, ce qui permet


de re-déclarer une classe déjà définie.

<script type = "text/javascript"> "use strict";


class myClass {};
class myClass {};
</script>

Firefox 64 :

Yandex :

<script type = "text/javascript"> "use strict";


var Foo = myClass {};

J.D.B. DIASOLUKA Nz. Luyalu 9 / 25 JavaScript Tome-III


Les CLASSES en JavaScript

class myClass {};


</script>

Firefox 64 :

Yandex :

Redéclaration d’une même « expression de class » :

<script type = "text/javascript"> "use strict";


var myClass = class {};
var myClass = class {};
</script>
OK, aucune reaction !

Expression simple :

<script type="text/javascript"> "use strict";


var Polygone = class {
constructor(longueur, largeur) {
this.nom = 'Polygone';
this.longueur = longueur/2;
this.largeur = largeur/2;
this.surf=(this.longueur*2)*(this.largeur*2);
this.qsurf=this.longueur*this.largeur;
}
}

let rect = new Polygone(10,15);


console.log("1/4 Surf=",rect.longueur*rect.largeur);
// 1/4 Surf= 37.5
console.log("1/4 Surf=",rect.qsurf);

J.D.B. DIASOLUKA Nz. Luyalu 10 / 25 JavaScript Tome-


III
Les CLASSES en JavaScript

// 1/4 Surf= 37.5


console.log("Surf=",rect.surf);
// Surf= 150
console.log("=========");
console.log(Polygone);
</script>

Firefox Quantum 62.0.2 :

Yandex Version 18.11.1.385 beta :

J.D.B. DIASOLUKA Nz. Luyalu 11 / 25 JavaScript Tome-


III
Les CLASSES en JavaScript

Expression de classe, nommée : permet de faire référence à la classe,


au sein du corps de la classe. Ce nom de classe ne sera visible que du
sein de la portée de l'expression de classe.

<script type="text/javascript"> "use strict";


var vClass = class ClassName {
constructor() {}
leNom() {
return ClassName.name;
}
}

var i = new vClass;


console.log(i.leNom()); // ClassName
///////// console.log(ClassName.name);
// ReferenceError: ClassName is not defined

console.log(vClass.name); // ClassName
</script>

Syntaxe générale d’une « class » :

var MaClasse = class [nomClasse] [extends] {


// corps de la classe
};

Le mot-clé « extends » (dans les déclarations ou les expressions de


classes) permet de créer une classe héritière (« sous-classe » ou
« classe-fille ») d'une autre.

<script type="text/javascript"> "use strict";


class Creancier {
constructor(id="Russe",q="1000") {
this.nom = id;
this.montant = q;
this.devise = " Roubles"
J.D.B. DIASOLUKA Nz. Luyalu 12 / 25 JavaScript Tome-
III
Les CLASSES en JavaScript

clause() {
return(this.nom + ' sollicite ' +
this.montant + this.devise);
}
}

class Debiteur extends Creancier {


clause() {
return(this.nom + ' rembourse ' +
this.montant + this.devise);
// Debiteur hérite de « nom » et « devise » de Creancier.
}
}

let kingandi = new Creancier("Elombe");


console.log(kingandi.clause());
// Elombe sollicite 1000 Roubles

let mosusu = new Debiteur("Boboto",20500);


console.log(mosusu.clause());
// Boboto rembourse 1000 Roubles

let lokuta = new Creancier(undefined,55000);


console.log(lokuta.clause());
// Boboto rembourse 1000 Roubles
</script>

<script type="text/javascript"> "use strict";


class Creancier {
constructor(id="Russe",q="1000") {
this.nom = id;
this.montant = q;
this.devise = " Roubles";

J.D.B. DIASOLUKA Nz. Luyalu 13 / 25 JavaScript Tome-


III
Les CLASSES en JavaScript

this.aspect = " Sérieux";


}

clause() {
return(
`${this.nom} ( ${this.aspect} )`+
` rembourse ${this.montant} ${this.devise}`
);
}
}

class Debiteur extends Creancier {


constructor (
id="Mowuta", q, motif="Projet",
credible=false) {
super(id, q);
this.raison = motif;
this.credi = credible;
this.aspect = "";
}

clause() {
let retval= `${this.nom} ( ${this.aspect} ) `+
`sollicite ${this.montant} ${this.devise}`+
`( ${this.raison} )`;
if(!this.credi) retval+=", refusé";
else retval+=", accordé ";
return retval;
// Debiteur hérite de « nom » et « montant » de Creancier.
}
}

let mosusu = new Creancier();


console.log(mosusu.clause());
// Boboto rembourse 1000 Roubles

let kingandi = new Debiteur(


"Elombe",15500,undefined,1);
console.log(kingandi.clause());
// Elombe sollicite 15500 Roubles (Projet), accordé
J.D.B. DIASOLUKA Nz. Luyalu 14 / 25 JavaScript Tome-
III
Les CLASSES en JavaScript

let lokuta = new Debiteur(


undefined,22500,"Construction");
console.log(lokuta.clause());
// Mowuta sollicite 22500 Roubles (Construction), refusé

let lolendo = new Creancier(


"Yewana",17500,"Lotissement",1);
console.log(lolendo.clause());
// Yewana rembourse 17500 Roubles
</script>

Les mots-clé « extends » et « super » :

« extends » indique que la « class » en cours est descendante (ou est


« extension ») de la classe parente qu’il désigne (qui le suit dans la
syntaxe).

Les arguments de « super » sont passés à la classe parente qui les


reçoit et les utilise en guise de paramètres quand cette classe parent
est appelée à partir de la classe en cours. « super » doit être utilisé
dans un constructeur et avant tout « this » éventuel.

<script type="text/javascript"> "use strict";


class Polygone {
constructor(hauteur, largeur) {
this.nom = 'Polygone';
this.hauteur = hauteur;
this.largeur = largeur;
this.tSurf="Haut="+this.hauteur+
", Larg="+this.largeur

J.D.B. DIASOLUKA Nz. Luyalu 15 / 25 JavaScript Tome-


III
Les CLASSES en JavaScript

this.Surf=this.tSurf+" => "+


this.hauteur*this.largeur
}
calc(){ return "Surf "+
this.nom+": "+this.Surf }
}

class Carré extends Polygone {


constructor(longueur) {
super(longueur);
this.nom = 'Carré';
this.tSurf="Longueur="+longueur
this.Surf=this.tSurf+" => "+
Math.pow(longueur,2);
}
}

class Volume extends Carré {


constructor(longueur,largeur,hauteur) {
super(longueur,largeur,hauteur);
this.nom = 'Volume';
this.tVol="Haut="+hauteur+", Larg="+
largeur+", Long="+longueur
this.Vol=this.tVol+" => "+
longueur*largeur*hauteur;
}
calc(){return this.nom+": "+this.Vol}
}

let iPolyg = new Polygone(10,20);


console.log(iPolyg.calc());
// Surf Polygone: Haut=10, Larg=20 => 200

let iSurf = new Carré(17);


console.log(iSurf.calc());
// Surf Carré: Longueur=17 => 289

let iVol = new Volume(3,5,7);


console.log(iVol.calc());
// Volume: Haut=7, Larg=5, Long=3 => 105
</script>
J.D.B. DIASOLUKA Nz. Luyalu 16 / 25 JavaScript Tome-
III
Les CLASSES en JavaScript

Appel d’une méthode du parent (super) à partir d’une classe fille :

<script type="text/javascript"> "use strict";


function Voiture (nom) {
this.nom = nom;
}

Voiture.prototype.roule = function () {
console.log(this.nom + ' file très vite.');
// Ferari file très vite.
}

class deRally extends Voiture {


roule() {
super.roule();
// Ferari file très vite (ligne 6).

console.log(this.nom + ' chancelle.');


// Ferari chancelle.
}
}

let v = new deRally('Ferari');


v.roule();
</script>

J.D.B. DIASOLUKA Nz. Luyalu 17 / 25 JavaScript Tome-


III
Les CLASSES en JavaScript

Prototype et « super » !

<script type="text/javascript"> "use strict";


var Voiture = {
roule() {
console.log(this.nom + ' file très vite.');
}
};

class deRally {
constructor(nom) {
this.nom = nom;
}
roule() {
super.roule();
console.log(this.nom + ' traîne.');
}
}
Object.setPrototypeOf(deRally.prototype, Voiture);
// Donne accès aux méthodes de Voiture.

var d = new deRally('Ferari');


d.roule();
</script>

Les classes peuvent inclure des getters et des setters :

<script type="text/javascript"> "use strict";


class User {
constructor(idName) {
console.log("Ds constructor.");
this.idName = idName; // invoque le setter
}

J.D.B. DIASOLUKA Nz. Luyalu 18 / 25 JavaScript Tome-


III
Les CLASSES en JavaScript

get idName() {
console.log(this._idName,"- de get");
return this._idName;
}

set idName(value) {
console.log("Ds setter.");
if (value.length < 4) {
console.log("idName trop court.");
return;
}
this._idName = value;
}
}

console.log('Avant let user=new User("John")');


let user = new User("Jerry");
console.log('Avant [console.log(user.idName)]');
console.log(user.idName,"- direct"); // Jerry

console.log('Avant user=new User("")');


user = new User("Jerry"); // idName trop court.
console.log('The END!');
</script>

Exécution-tracée:

J.D.B. DIASOLUKA Nz. Luyalu 19 / 25 JavaScript Tome-


III
Les CLASSES en JavaScript

« symbole . species » permet de surcharger le constructeur par dé-


faut d’une méthode qui renvoie un objet Array avec une sous-classe
par exemple MonArray e.g. la méthode map() , par exemple pour
modifier le format <du résultat.

<script type="text/javascript"> "use strict";


class MonArray extends Array {
static get [Symbol.species]() { return Object; }
// On surcharge species avec le constructeur Object
}

var a = new MonArray("2","4","6");


console.log(a instanceof MonArray); // true

var mapped = a.map(x => x * x);


console.log(mapped); // Number {3, 0: 4, 1: 16, 2: 36}

console.log(MonArray); //class MonArray extends Array {}

console.log(mapped instanceof MonArray); // false


console.log(mapped instanceof Array); // false
console.log(mapped instanceof Object); // true
console.log(mapped instanceof Number); // true

console.log("==========");

class MonArray2 extends Array {


static get [Symbol.species]() { return Array; }
// On surcharge species avec le constructeur Array
}
var a = new MonArray2("2","4","6");
var mapped = a.map(x => x * x);
console.log(mapped);// Array [ 4, 16, 36 ]

console.log(MonArray); //class MonArray extends Array {}


console.log(mapped instanceof MonArray2); // false
console.log(mapped instanceof Array); // true
console.log(mapped instanceof Object); // true
console.log(mapped instanceof Number); // false
</script>
J.D.B. DIASOLUKA Nz. Luyalu 20 / 25 JavaScript Tome-
III
Les CLASSES en JavaScript

J.D.B. DIASOLUKA Nz. Luyalu 21 / 25 JavaScript Tome-


III
Les CLASSES en JavaScript

Kinshasa, le mardi 22 janvier 2019 - 9:22:28 AM

Mots-clés :

JAVASCRIPT, Programmation Internet, fonction fléchée, sloppy


mode, mode strict, prototype, objet ordinaire, objet exotique, objet
standard, built-in object, Scope, contexte d’exécution, Domaine, Por-
tée, Étendue, Visibilité, Accessibilité, durée de vie, Es8,
ECMASCRIPT, LiveScript, extra-dimensionnels, entités éthériques
non-biologiques, TC39, ECMA, Kaprekar

J.D.B. DIASOLUKA Nz. Luyalu 22 / 25 JavaScript Tome-


III
Les CLASSES en JavaScript

DIASOLUKA Nz. Luyalu


Docteur en Médecine, Chirurgie & Accouchements (1977),
CNOM : 0866 - Spécialiste en ophtalmologie (1980)
Études humanités : Scientifique - Mathématiques & Physique.
Informaticien-amateur, Programmeur et WebMaster.

Chercheur indépendant, autonome et autofinancé, bénévole, sans


aucun conflit d’intérêt ou liens d'intérêts ou contrainte
promotionnelle avec qui qu’il soit ou quelqu’organisme ou
institution / organisation que ce soit, étatique, paraétatique ou
privé, industriel ou commercial en relation avec le sujet présenté.

+243 - 851278216 - 899508675 - 991239212 - 902263541 - 813572818

diasfb@mail2world.com

Autre Lecture :
https://www.scribd.com/document/374738470/Le-Plus-Grand-Secret-de-La-
Creation

D’autres publications pouvant aussi intéresser :

• https://www.scribd.com/document/377036251/Le-
Dosage-Des-Medicaments-en-Cac-Cas
• https://www.scribd.com/document/377035454/Le-
Hasard-Des-Thermometres-Non-contact-a-Infrarouge

J.D.B. DIASOLUKA Nz. Luyalu 23 / 25 JavaScript Tome-


III
Les CLASSES en JavaScript

• https://www.scribd.com/document/376222482/Petite-
Introduction-Aux-Fonctions-JavaScript
• https://www.scribd.com/document/376221919/La-Foi-
en-Jesus-Christ-Pour-Quoi-Faire
• https://www.scribd.com/document/375689778/Lacuite-
visuelle-angulaire
• https://www.scribd.com/document/375349851/La-
variable-This

https://www.scribd.com/document/375024162/Fonctions-
Imbriquees-en-JS
• https://www.scribd.com/document/374789297/Format-
Interne-Des-Objets-JavaScript

https://www.scribd.com/document/374788758/Iterations-
en-JavaScript
• https://www.scribd.com/document/374738470/Le-Plus-
Grand-Secret-de-La-Creation
• https://www.scribd.com/document/374597969/Nouvelle-
Formule-d-IMC-indice-de-doduite-Selon-Dr-Diasoluka
• https://www.scribd.com/document/373847209/Property-
Descriptors
• https://www.scribd.com/document/373833282/l-Objet-
Global-Window

https://www.scribd.com/document/372665249/Javascript-
Tome-II
J.D.B. DIASOLUKA Nz. Luyalu 24 / 25 JavaScript Tome-
III
Les CLASSES en JavaScript

• https://www.scribd.com/document/355291488/motilite-
oculaire-2
• https://www.scribd.com/document/355291239/motilite-
oculaire-I
• https://www.scribd.com/document/355290248/Script-d-
Analyses-Des-Reflexes-Pupillomoteurs

https://www.scribd.com/document/321168468/Renseigne
ments-Id-et-Anthropometriques

https://www.scribd.com/document/320856721/Emission-
31-Jul-2016

https://www.scribd.com/document/318182982/Complicati
on-Visuelle-du-Traitement-de-La-Malaria
• https://www.scribd.com/document/318180637/Rapport-
Entre-Oxymetrie-Et-Type-Respiration

https://www.scribd.com/document/315746265/Classificati
on-Des-Medicaments

https://www.scribd.com/document/315745909/Incongruen
ces-Heresies-et-Heterodoxies-de-la-Notion-de-
Laboratoire
• https://www.scribd.com/document/315745725/Rapport-
Entre-Oxymetrie-Et-Type-Respiration

J.D.B. DIASOLUKA Nz. Luyalu 25 / 25 JavaScript Tome-


III

Potrebbero piacerti anche