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()
}
}