Les éléments de la POO dans le contexte du Web
La création de conteneurs d’objets
Disposition du contenu de ces objets dans la page du client.
On veut continuer à apprendre javascript
Introduction à la conception d’applications : parce qu'il faut
Méthode Agile: Pour être trendy
Conception générale et détaillée: Parce que nous aimons le code.
Étudié en mathématiques
Programmeur avant toutes choses
Python
Java
Clojure
Go
Rust
JavaScript/TypeScript
Travaillé à trop de places.
$5^{ime}$ cours que j'enseigne
J'ai deux chiens (Molly & Pepper)
J'habite avec un chat
Votre nom
Vous étudiez en quoi
Vous aimez quoi
Language de programmation préféré
Pondération 1-2-2
Comment me contacter (didier.amyot@collegeahuntsic.qc.ca)
Horaires - mercredi & vendredi de 13h00 à 16h00
Cours du mercredi sur place
Cours du vendredi, sur "meet"
Présence en classe
Évaluations
Plagiat (ChatGPT)
Nous avons un gros congé pour le temps des fêtes
Grêve des enseignants
Reprise de cours?
Horaire des évaluations
// For values that change
let name = "didier";
name = "paulette";
// For values that never change
const age = 37;
| nom | exemple | description |
|---|---|---|
| boolean | true/false |
Représente un valeur vraie ou fausse |
| number | 12, 0, -19, 3.14159 |
Représente un nombre quelconque |
| String | "Bonjour", 'les amis' |
Représente du texte |
| undefined | undefined |
Représente un inconnue provenant de javascript |
| null | null |
Représente un inconnue provenant du programmeur |
Pour que deux variables soient === il faut que les deux variables aillent le même type et la même valeur.
let message1 = "Bonjour le monde"
let message2 = "привет мир";
let message1EqualsMessage2 = (message1 === message2); // false
| Définition | Opérateur | Exemple |
|---|---|---|
| Égalité entre deux boolean | === |
true === true |
| et logique | && |
true && true |
| ou logique | || |
true || false |
| Négatif | ! |
!false |
| Définition | Opérateur | Exemple |
|---|---|---|
| Égalité entre deux nombres | === |
10 === 10 |
| Somme | + |
2 + 2 === 4 |
| Produit | * |
3 * 4 === 12 |
| Division | / |
12 / 3 === 12 |
| Modulo | % |
7 % 3 === 1 |
| Définition | Opérateur | Exemple |
|---|---|---|
| Égalité entre deux nombres | === |
2 + 2 === 4 |
| Strictement plus petit | < |
2 < 4 |
| Plus petit (ou égale) | <= |
4 <= 4 |
| Strictement plus grand | > |
4 > 2 |
| Plus grand (ou égale) | >= |
4 >= 4 |
| Définition | Opérateur | Exemple |
|---|---|---|
| Égalité entre deux strings | === |
"Japon" === "Japon" |
| concaténation | + |
"Bonjour " + "le monde" === "Bonjour le monde" |
| Définition | Méthode | Exemple | Notes |
|---|---|---|---|
| Nombre de lettres dans la string | .length |
"Japon".length === 5 |
plein de bug pour les gens qui écrivent dans des langues bizzards* |
| Mettre en lettre majuscule | .toUpperCase() |
"Japon".toUpperCase() === "JAPON" |
|
| Mettre en lettre minuscule | .toLowerCase() |
"Japon".toLowerCase() === "japon" |
|
| Lettre à une position précise | .charAt() |
"Japon".charAt(3) === "o" |
plein de bug pour les gens qui écrivent dans des langues bizzards* |
langues bizzards: surtout les emoji. Même le chinois langues bizzards m'a l'air de fonctionnner
ifs¶if(age > 18){
alert("the user is major");
} else {
alert("the user is minor");
}
if(age > 21){
alert("the user is major in the US.");
} else if (age > 18) {
alert("the user is major in real countries but not in the empire.");
}else {
alert("the user is minor.");
}
else¶if(age > 18){
alert("the user is major");
}
On beaucoup aime les if sans else
On aime les if avec else
On tollère les if avec des else if
if(la condition){
// quoi faire si la condition est vraie
} else {
// quoi faire si la condition est fausse
}
Toutes valeurs sauf les valeurs si bas sont considérées comme vraies.
null, la valeur nullundefined, la valeur undefinedfalse, la fauxNaN, not a number (exemple parseInt("sdjkds"))0, zero"", le string videlet name = "";
if(!name){
name = "no name";
}
console.log(name);
let name;
if(!name){
name = "no name";
}
console.log(name);
let name = null;
if(!name){
name = "no name";
}
console.log(name);
let person = {};
if(!person.name){
person.name = "";
}
console.log(person);
let persons = [];
if(!persons.length){
persons.push({name: "didier"});
}
console.log(persons);
En mathématiques, une fonction est un type de relation $f$ entre deux variables. On appelle cette relation une fonction lorsque chaque valeur de la variable indépendante est associée à une et une seule valeur de la variable dépendante.
-- https://www.alloprof.qc.ca/fr/eleves/bv/mathematiques/relations-et-fonctions-m1095
function sayHello(){
alert("hello world");
}
function addNumber(a, b){
return a + b;
}
function isMajorMessage(age){
if(age < 18){
return "user is minor";
}
if(age < 21){
return "user is minor in crazy countries";
}
return "user is major"
}
Les arguments d'une fonction sont connue de la fonction seulement.
Les deux fonctions ci-bas sont les mêmes
function add(a, b){
return a + b;
}
function add(x, y){
return x + y;
}
Le nom d'une fonction doit être unique
Le nom de la fonction devrait être un verbe
Moins que la fonction est utilisé de fois, plus son nom devrait être long
function add2AndMultiplyBy3(a){
return (a + 2) * 3;
}
Une fonction peut retourner au maximum une seule valeure
À l'instant que la fonction retourne, l'execution de la fonction se termine
function getMinorityStatus(age){
if(age < 18){
return "minor";
}
if(age < 21){
return "minor in the empire";
}
return "major";
}
console.log(getMinorityStatus(12)); // "minor"
console.log(getMinorityStatus(19)); // "minor in the empire"
console.log(getMinorityStatus(87)); // "major"
On utilise la notation nomDeLaFonction(argument1, argument2)
function add(a, b){
return a + b;
}
function multiply(a, b){
return a * b;
}
console.log(add(2, 3));
console.log(add(2, multiply(4, 5)));
let x = multiply(2, 3);
console.log(add(2, x));
console.log(
add(8,
multiply(10, 6))
);
for(let i = 0; i < 10; i ++){
console.log(i);
}
let i = 0i < 10i = i + 1let emptyList = [];
let beerList = ["bud weiser", "ipa du nord-est", "headdy topper"];
let grades = [90, 65, 40, 55];
let beerList = ["bud weiser", "ipa du nord-est", "headdy topper"];
// longeur d'une liste
console.log(beerList.length);
// ajouter un élément à une liste
beerList.push("peche mortel");
// element d'une liste
// l'indice commence par 0!!!!!!!!!
alert(beerList[2]); // "headdy topper"
(on aime beaucoup les boucles for each)
for(const beer of beerList){
console.log(beer);
}
Un objet javascript est une collection clé/valeur
Les clés sont des strings
En d'autres languages
let beer = {
nom: "Péché Mortel",
brasserie: "Dieu du Ciel!",
quantity: 350,
prix: 5.99,
}
{}
let beer = {
nom: "Péché Mortel",
brasserie: "Dieu du Ciel!",
quantity: 350,
prix: 5.99,
}
// Prendre une valeur par une variable
console.log(beer.name)
// associer une nouvelle valeur
beer.nom = "grande noirceur";
// Prendre toutes les clés
Object.keys(beer);
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
let beer = {
nom: "Péché Mortel",
brasserie: "Dieu du Ciel!",
quantity: 350,
prix: 5.99,
}
for(let key of Object.keys(beer)){
let value = beer[key];
console.log(key + " : " + value);
}
Faisons la question 6.o. de https://didier-ahuntsic.gitlab.io/cours-420-298-ah/_exercices/007.pdf
Pour ce faire, nous allons procéder ainsi:
faire un plan
suivre le plan
Un string qui contient un text avec plusieurs lignes
Un string qui permet de remplacer façilement une variable
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
let message = `Ceci est un texte normal`;
let multiLineMessage = `un
deux
trois`;
console.log(multiLineMessage)
let multiLineMessage = `un
deux
trois`;
console.log("->" + multiLineMessage + "<-");
->un deux trois<-
let name = "Colette"
let message = `Bonjour ${name}`;
console.log(message)
let name = "Colette"
let message = `Bonjour ${name}`;
console.log(message)
Bonjour Colette
let name = "Colette"
let anneeCourrante = 2023;
let anneeDeNaissance = 1947;
let message = `Bonjour ${name}, vous avez ${anneeCourrante - anneeDeNaissance} années`;
console.log(message)
Bonjour Colette, vous avez 76 années
let message = `Ceci est totallement \${foo}`;
console.log(message)
Ceci est totallement ${foo}
#
###
#####
#######
#########
Écrire un string
Bonjour, mon nom est André André et j'habite Laval. J'ai 3 chars.
Pour
{
firstName: "André",
lastName: "André",
city: "Laval",
cars: ["civic", "mustang", "F150"],
}
Les programmes consistent habituellement en plusieurs fichiers
Les programmes utilisent habituellement des dépendances externes (react, mithril, angular, lodash)
Votre programme sera probablement importer par d'autre programmes
Il est façile de copier quelque chose
Il est façile de réutiliser quelque chose
On veut calculer la moyenne d'un groupe d'étudiant. Nous travaillons dans un fichier students.js
et nous avons un fichier stats.js avec des fonctions statistiques fait par une statisticienne.
stats.js¶// stats.js
function average(lst){
if(lst.length < 1){
return NaN;
}
let sum = 0;
let n = 0;
for(const e of lst){
sum += e;
n += 1;
}
return sum / n;
}
students.js¶// students.js
function getFinalGrades(students){
const grades = [];
for(const student of students){
if(student.finalGrade){
grades.push(finalGrade);
}
}
return grades;
}
function studentAverage(students){
const finalGrades = getFinalGrades(students);
const ret = average(finalGrades);
if(isNaN(ret)){
return "Aucune note entrées";
}
return ret + "%";
}
Être capable de "merger" les deux fichiers dans le bon ordre
Être capable d'importer des fonction de n'importe où
C'est un fichier javascript
Le fichier utilise une extension .js ou .jsm (javascript module)
C'est une fichier qui peut importer d'autres modules
C'est une fichier qui peut exporter des choses
C'est un fichier qui est dans son propre "scope"/"namespace"
Si un module students.js utilise la fonction average du module stats.js on dira que le module students.js importe la fonction average du module stats.js.
Si la fonction average du module stats.js peut être importer par un aute module, on dira que la fonction average est exporté par stats.js.
Un module stats.js doit être consentant pour exporter une fonction average.
Le module students.js n'a pas besoin de l'accord stats.js pour importer la fonction average
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>title</title>
<script type="module" src="script.js"></script>
</head>
<body>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>title</title>
<script type="module" src="script.js"></script>
</head>
<body>
<button onclick=sayHello() id="hello-button">Say Hello</button>
</body>
</html>
script.js contient la fonction sayHello(), cliquer le bouton ne fera rien :(function sayHello(){
alert("Bonjour monde!");
}
document.getElementById("hello-button").addEventListener('click', sayHello);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<script type="module" src="script.js"></script>
</head>
<body>
<button id="hello-button">Say Hello</button>
</body>
</html>
import {average} from "./stats.js";
import {average} from "https://cdn.jsdelivr.net/gh/didiercrunch/cours-420-301-ah@main/modules-examples/stats.js";
import {average} from "https://cdn.jsdelivr.net/gh/didiercrunch/cours-420-301-ah@main/modules-examples/stats.js";
console.log(average([1,2,3,4]))
2.5
import {average} from "./stats.js";
^ ^ ^ ^
1 2 3 4
import est réservéfrom est réservéimport {average} from "./stats.js";
console.log(average([10, 20, 30]));
averageaverage définit dans ./stats.jsimport {average, std} from "./stats.js";
console.log(average([10, 20, 30]));
console.log(std([10, 20, 30]));
average et stdaverage et std définient dans ./stats.jsimport {std as standardDeviation} from "./stats.js";
console.log(standardDeviation([10, 20, 30]));
std mais la renommons standardDeviation./stats.jsimport * as stats from "./stats.js";
console.log(stats.average([10, 20, 30]));
/stats.js et les mettons dans un objet stats./stats.js
export const INFINITY = 30;
export function average(lst){
return 0;
}
export function std(lst){
return 0;
}
export const INFINITY = 30;
^ ^ ^ ^
1 2 3 4
export est réservéexport function average(lst){
return 0;
}
Une super BD https://hacks.mozilla.org/2018/03/es-modules-a-cartoon-deep-dive/
La vraie doc: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules
V8 (aka google) https://v8.dev/features/modules
UTC est une échelle de temps comprise entre le temps atomique international (TAI) qui est stable mais déconnecté de la rotation de la Terre et le temps universel (TU), directement lié à la rotation de la Terre et donc lentement variable.
Dans « Temps Universel Coordonné » UTC, le terme « coordonné » indique que ce temps s’écoule de façon identique à celui du Temps Atomique International, il en a la stabilité et l’exactitude à un nombre entier de secondes près, et grâce à un mécanisme d'ajustement mis en œuvre chaque fois que nécessaire, il est décalé d'une seconde pour qu'il reste proche du temps universel à moins de 0,9 s près.
-- wikipedia
Les serveurs sont habituellement en temps UTC
Les navigateurs sont habituellement en temps locale
Les fuseaux horaires se comparent à UTC zero (aka, heure de londres en hivers)
Los Angeles, États-Unis (UTC-8) : 04:00
Chicago, États-Unis (UTC-6) : 06:00
New York, États-Unis (UTC-5) : 07:00
Halifax, Canada (UTC-4) : 08:00
Londres, Royaume-Uni (UTC±0) : 12:00
L'heure Unix ou heure Posix est une mesure du temps fondée sur le nombre de secondes écoulées depuis le 1er janvier 1970 00:00:00 UTC, hors secondes intercalaires. Elle est utilisée principalement dans les systèmes qui respectent la norme POSIX1, dont les systèmes de type Unix, d'où son nom. C'est la représentation POSIX du temps.
On peut demander à javascript quelle est l'heure UNIX
Ce que javascript nous retourne est un nombre en milli secondes
let unixTimestamp = Date.now();
console.log(unixTimestamp) // 1701713417357
Ça peut nous aider à calculer le durée entre deux événements
Mais, sincèrement, quelle est l'heure à 1701713417357?
let date = new Date();
let dateString = date.toString();
console.log(dateString) // Mon Dec 04 2023 13:21:26 GMT-0500 (heure normale de l’Est)
let date = new Date();
^ ^ ^
3 1 2
let date = new Date()
let dateString = date.toLocaleString();
console.log(dateString)
2023-12-04 13 h 24 min 10 s
let date = new Date()
newnew Date() créer un "objet" de de type Date> date.
constructor getMilliseconds getUTCFullYear setYear
toString setMilliseconds setUTCFullYear toJSON
toDateString getMinutes getUTCHours toLocaleString
toTimeString setMinutes setUTCHours toLocaleDateString
toISOString getMonth getUTCMilliseconds toLocaleTimeString
toUTCString setMonth setUTCMilliseconds __defineGetter__
toGMTString getSeconds getUTCMinutes __defineSetter__
getDate setSeconds setUTCMinutes hasOwnProperty
setDate getTime getUTCMonth __lookupGetter__
getDay setTime setUTCMonth __lookupSetter__
getFullYear getTimezoneOffset getUTCSeconds isPrototypeOf
setFullYear getUTCDate setUTCSeconds propertyIsEnumerable
getHours setUTCDate valueOf
setHours getUTCDay getYear
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date
Quelle heure est-il localement?
Quelle mois sommes-nous présentement? Écrire le mois mot.
Quelle année sommes-nous?
Quel est l'époch time présentement (en seconde)?
Quelles minutes dans l'heure est-il présentement?
Dans quel fuseau horaire vous trouvez vous présentement (en heure par rapport à UTC-0)?
Quelle est l'epoch time dans exactement 1 an?
Quelle était l'époch time à ce moment exact le mois passé?
Objects hide their data behind abstractions and expose functions that operate on that data. Data structures expose their data and have no meaningful functions.
-- uncle bob
On veut avoir un paquet de méthodes toutes lié entre elles qui gère les mêmes données.
Date¶let date = new Date();
^ ^ ^
3 1 2
let date = new Date();
date.setFullYear(2024);
console.log("L'époch time dans 1 an sera exactement " + date.getTime() + " ms");
Ici, l'instance date "cache" plein de choses
Une classe représente donc une catégorie d'objets. Elle apparaît aussi comme un moule ou une usine à partir de laquelle il est possible de créer des objets ; c'est en quelque sorte une « boîte à outils » qui permet de fabriquer un objet. On parle alors d'un objet en tant qu'instance d'une classe (création d'un objet ayant les propriétés de la classe).
-- wikipedia
Une classe, est une ensemble de fonction qu'on veut associer à des données que les fonctions partagent entre elles.
Les fonctions d'une classe sont appelées méthodes. Les données de la classes sont nommées attributs.
c'est deux équipes qui jouent l'une contre l'autre et qui "compte" dans le but de leurs adversaire. L'équipe qui compte le plus de but gagne la partie.
-- un expert de hockey annonyme
import {HockeyGame} from "https://cdn.jsdelivr.net/gh/didiercrunch/cours-420-301-ah@006.1/modules-examples/mod.js";
let hockeyGame = new HockeyGame();
hockeyGame.awayTeamScores();
hockeyGame.homeTeamScores();
hockeyGame.homeTeamScores();
hockeyGame.awayTeamScores();
hockeyGame.homeTeamScores();
console.log(`Le gagnant de la partie est: ${hockeyGame.winner()}`)
Le gagnant de la partie est: home
C'est quelqu'un avec un prénom et un nom de famille qui est né à une date précise
-- un expert de hockey annonyme
import {HockeyPlayer} from "https://cdn.jsdelivr.net/gh/didiercrunch/cours-420-301-ah@006.1/modules-examples/mod.js";
let player = new HockeyPlayer("didier", "amyot", new Date(1983, 9, 9))
console.log(player.currentAge());
40
La méthode constructor est une méthode qui est utilisée pour créer et initialiser un objet lorsqu'on utilise le mot clé class.
let player = new HockeyPlayer("didier", "amyot", new Date(1983, 9, 9))
^ ^ ^
1 2 3
new
Une classe, est un ensemble de fonctions qu'on veut associer à des données que les fonctions partagent entre elles.
Les fonctions d'une classe sont appelées méthodes. Les données de la classes sont nommées attributs.
URL¶const url = new URL("https://www.example.com/personne?nom=didier&age=38");
console.log(url.hostname) // www.example.com
console.log(url.search); // ?nom=didier&age=38
console.log(url.pathname) // /personne
console.log(url.pathname) // url.protocol
class Politicien{
}
const politicien = new Politicien();
Politicien est un peu comme l'objet vide {}Politicienclass JackOfAllTrade{
add(a, b){
return a + b;
}
multiply(a, b){
return a * b;
}
}
const jackOfAllTrade = new JackOfAllTrade();
console.log(jackOfAllTrade.add(4, 7));
console.log(jackOfAllTrade.multiply(7, 3));
Pour utiliser les méthodes JackOfAllTrade il faut avant, créer une instance de la classe:
const jackOfAllTrade = new JackOfAllTrade();
L'utilisation des méthodes se fait avec la convention <instance>.<méthode>
console.log(jackOfAllTrade.add(4, 7))
class JackOfAllTrade{
add(a, b){
return a + b;
}
}
Les méthodes sont écrites à l'intérieur de la classe
La syntaxe d'une méthode est la même que celle d'une fonction... sauf sans le mot réservé function.
Une méthode est "genre" une fonction
toSnakeCase est une fonction qui convertie une phrase en snake case. Par exemple petit lapin blanc deviendra petit_lapin_blanctoKebabCase est une fonction qui convertie une phrase en kebab case. Par exemple petit lapin blanc deviendra petit-lapin-blanctoCamelCase est une fonction qui convertie une phrase en camel case. Par exemple petit lapin blanc deviendra petitLapinBlancon aime javascript dans les différents typesthis¶
Imaginons créer ajouter une méthode add2plus5 dans la classe JackOfAllTrade
class JackOfAllTrade{
add2plus5(a){
return (a + 2) * 5;
}
}
add et multiply déjà existantesLa bonne solution est la suivante.
class JackOfAllTrade{
add2plus5(a){
const aPlus2 = this.add(a,2)
return this.multiply(aPlus2, 5);
}
}
this¶Le mot réservé this permet à une méthode d'appeler une autre méthode dans une classe!
this.
Lorsque nous appelons new Person("didier", 38) le constructeur est appelé.
Le constructeur est une fonction "spéciale" qui est uniquement appelé lors de la création d'une instance
Le constructeur devrait uniquement "placer" des données
Le constructeur est une méthode appelé "constructor"
class Point{
constructor(x, y){
this.x = x;
this.y = y;
}
distanceFromOrigin(){
return Math.sqrt(this.x * this.x + this.y * this.y);
}
}
p = new Point(3, 4);
console.log(p.distanceFromOrigin());
Un constructeur ne devrait avoir que des
this.chose = choseet, peut-être, des validations très simple. Tout le reste ne devrait pas être dans un constructeur
-- le meilleur programmeur au monde
function add(a, b){
return a + b;
}
add peut être appelé avec n'importe quoiadd "font du sense"let x = 10;
x = doSomethingToIntegerAndReturnAString(x);
doSomethingToAString(x);
Le type des variable n'est pas forcément constant
Dans l'exemple ci-haut, x passe d'un number à un string
Dans un programme javascript, le programmeur doit s'assurer que tous les paramêtre que les fonctions recoivent font du sense.
let x = generateX();
let y = generateY();
let z = mergeXAndY(x, y);
z = incrementZ(z);
printAll(x, y, z);
Nous serions capable de savoir au compile time (sans executer le code) si notre programme est valide
let x = generateX(); // generateX retourne un "number"
let y = generateY(); // generateY retourne un "String"
let z = mergeXAndY(x, y); // mergeXAndY prend un "number" et
// un "string" et retourne un "number"
z = incrementZ(z); // incrementZ prend un "number" et
// retourne un "number"
printAll(x, y, z); // prend un number, un string et un number
Présentement, le language le plus populaire pour "typer du javascript" est TypeScript:
function generateX(): number {
return 22;
}
function generateY(): String {
return "hello";
}
function mergeXAndY(x: number, y: String): number {
return x + y.length;
}
function incrementZ(z: number): number{
return z + 908;
}
function printAll(x: number, y: String, z: number): void {
console.log(`number: ${x} , number: ${ y}, number: ${z}`);
}
let x = generateX();
let y = generateY();
let z = mergeXAndY(x, y);
z = incrementZ(z);
printAll(x, y, z);
flowchart LR
TypeScript --vérification--> JavaScript
JavaScript --> Browser
Dans les languages OOP fortement typé classiques (Java, C#,... mais surtout Java 1.1), les fonctions utilises les classes pour décrire ce qu'elles peuvent recevoir en argument et ce qu'elles retournes.
function getBestTeamName(team1: Team, team2: Team): String {
}
function getBestTeamName(team1: Team, team2: Team): String {
}
const les3 = new DodgeballTeam("Les 3");
const les5 = new DodgeballTeam("Les 5");
console.log(getBestTeamName(les3, les5)); // Erreur! DodgeballTeam n'est pas un Team
Il faut donc être capable de dire qu'un DodgeballTeam est un Team
flowchart TD
Team --> DodgeballTeam
On veut créer une classe DodgeballTeam qui est pratiquemement la classe Team plus des extra
Partout où une instance de Team est acceptée, il faut qu'une instance de DodgeballTeam soit acceptée.
class Team {
constructor(partiesGagnes, partiesPerdues){
this.partiesGagnes = partiesGagnes;
this.partiesPerdues = partiesPerdues;
}
getDiff(){
return this.partiesGagnes - this.partiesPerdues;
}
}
class DodgeballTeam extends Team {
constructor(partiesGagnes, partiesPerdues, ballonsAttrapes){
super(partiesGagnes, partiesPerdues);
this.ballonsAttrapes = ballonsAttrapes
}
ballonsAttrapesParParties(){
let parties = this.partiesGagnes + this.partiesPerdues;
return this.ballonsAttrapes / parties;
}
}
Mots clées:
extends: est le mot magique pour créer une sous classe.
super¶Est l'équivalent du mot this mais parle de la classe du haut.
this est à propos de la classe présente ou parent...
super¶class Foo {
foo(){
return 10;
}
}
class Bar extends Foo{
foo(){
return 1000;
}
bar(){
return super.foo();
}
}
const bar = new Bar();
console.log(bar.foo()) // 1000
console.log(bar.bar()) // 10
sous-classe (sub-class) didier aime beaucoup ce terme. Le "sous" est entendu au point de vue mathématiques; un sous groupe d'un groupe libre est... libre!
super-classe (super-class) didier accepte ce terme par manque d'un meilleur terme. Le terme "super" veut dire la classe parente direct
classe enfant (child class) didier n'aime vraiment pas ce terme.
Fuck la patriachie
classe parent (parent class) didier n'aime vraiment pas ce terme.
Fuck la patriachie
polymorphisme est le concept consistant à fournir une interface unique à des entités pouvant avoir différents types. --- wikipedia
class Rectangle {
constructor(hauteur, largeur) {
this.hauteur = hauteur;
this.largeur = largeur;
}
aire() {
return this.hauteur * this.largeur;
}
}
Rectanglenommé Carreperimetre à Carreclass Carre extends Rectangle {
constructor(cote) {
super(cote, cote);
}
perimetre(){
return 4 * this.hauteur
}
}
Pour appeler le constructeur super dans une sous classe est d'utiliser super().
On peut façilement ajouter une fonction dans une sous-classe
class User {
constructor(id, username) {
this.id = id;
this.username = username;
}
idAdmin() {
return false;
}
}
Usernommé AdminisAdminclass Admin extends User {
idAdmin() {
return true;
}
}
override une méthode dans une sous-classe.class Animal {
constructor() {
this.state = "arret";
}
courrir() {
this.state = "courrir";
}
arret() {
this.state = "arret";
}
getState(){
return this.state
}
}
Animal nommé Lapinclass Lapin extends Animal {
constructor() {
super();
this.isHidden = false;
}
hide(){
this.isHidden = true;
}
unHide(){
this.isHidden = false;
}
courrir(){
if(this.isHidden){
return;
}
super.courrir();
}
}
Un sous-constructeur devrait toujours appeler super
Nous ne devrillions pratiquement jamais overrider une méthode
Lorsque nous overriderons une méthode, nous devrillions toujours appeler la super méthode
On créer une fonction qui retourne différent type d'objets dépendamment de ce que la fonction prend en argument.
function getUser(loggedInRequest){
if(request.isAdmin){
return new Admin(request.id, request.username);
}
return new User(request.id, request.username);
}
instanceof¶Pour savoir si une instance x est instance de la class Foo il faut utiliser...
let foo = new Foo();
let bar = new Bar();
foo instanceof Foo;
bar instanceof Bar; // true ssi Bar est une sous-classe de Foo
Les frameworks modernes utilisent de moins en moins l'héritage
Les nouveaux languages de programmation ne permettent pas l'héritage
Les principes "SOLID" font en sorte que l'utilisation de l'héritages est assez restrain
Dans les languages plus fortement typé, l'héritage à été remplacé par les "interfaces"
flowchart TD
Team --> DodgeballTeam
DodgeballTeam --> MixedDodgeballTeam
Regardons le cas d'une équipe de dodgeball mixte. Dans une équipe de dodgeball mixte, il faut absolutment qu'au moins la moité de l'équipe soit des femmes
class Team {
constructor(partiesGagnes, partiesPerdues){
this.partiesGagnes = partiesGagnes;
this.partiesPerdues = partiesPerdues;
}
getDiff(){
return this.partiesGagnes - this.partiesPerdues;
}
}
class GameStats {
constructor(partiesGagnes, partiesPerdues){
this.partiesGagnes = partiesGagnes;
this.partiesPerdues = partiesPerdues;
}
getDiff(){
return this.partiesGagnes - this.partiesPerdues;
}
}
super classe, souvant son nom fait aucun sense. (exemple, CoreUser, UserBase, AbstractUser, ...)class Players {
constructor(players){
this.players = players;
}
totalNumberOfPlayer(){
let ret = 0;
for(const player of this.players){
if(!player.isAngered){
ret += 1;
}
}
return ret;
}
totalNumberOfFemalePlayer(){
let ret = 0;
for(const player of this.players){
if(!player.isAngered && player.gender === "female"){
ret += 1;
}
}
return ret;
}
}
class MixedDodgeballTeam{
constructor(players, partiesGagnes, partiesPerdues){
this.players = players;
this.stats = new GameStats(partiesGagnes, partiesPerdues);
}
getDiff(){
return this.stats.getDiff();
}
isValid(){
return this.players.totalNumberOfPlayer() < 2 * this.players.totalNumberOfFemalePlayer()
}
}