Archives Wild Code School
Typescript

TypeScript : programmation orientée objet

Quête 5 sur 5

Dans cette quête tu vas apprendre la programmation orientée objet en TypeScript.

Objectifs

  • Comprendre les interfaces, les classes et l'héritage en TypeScript

Les interfaces

En TypeScript, les interfaces décrivent le modèle d'un objet JavaScript : elles peuvent contenir des attributs et des déclarations de méthodes qui doivent être au minimum présent dans l'objet. Si une méthode est déclarée dans une interface, il faut l'implémenter dans la classe qui utilisera cette interface. Une interface est également un type de données, c'est-à-dire qu'on peut très bien définir une interface Vehicule puis choisir qu'une fonction prenne en paramètre une variable de type Vehicule :

shell
interface Vehicule {
  brand: string;
  model: string;
  firstRegistrationYear: number;
}

function drive(vehicule: Vehicule) {
  console.log("I'm driving my " + vehicule.brand + " " + vehicule.model + " from " + vehicule.firstRegistrationYear);
}

Nous sommes donc obligés d'appeler la fonction drive avec un objet contenant les champs brand et model de type string et le champ firstRegistrationYear de type number :

shell
var myVehicule = {
  brand: "Alfa Romeo",
  model: "159 SW",
  firstRegistrationYear: 2007
};
drive(myVehicule);

I'm driving my Alfa Romeo 159 SW from 2007

Mais on peut très bien l'appeler avec un objet contenant d'autres attributs :

shell
var myVehicule = {
  brand: "Alfa Romeo",
  model: "159 SW",
  firstRegistrationYear: 2007,
  horsePower: 200,
  width: 1828,
  length: 4660
};
drive(myVehicule);

I'm driving my Alfa Romeo 159 SW from 2007

↗
TypeScript Interfaces

Explique les interfaces

typescriptlang.org

Les classes

En TypeScript, une classe est la définition d'un objet, qui peut contenir des attributs et des méthodes (on évitera le terme fonction dans l'orienté objet).

Par exemple, on peut créer la classe Car :

shell
class Car {
  brand: string;
  model: string;
  firstRegistrationYear: number;
  horsePower: number;
  width: number;
  length: number;

  drive() {
    console.log("I'm driving my " + this.brand + " " + this.model + " from " + this.firstRegistrationYear);
  }
}

Créons un objet de type Car, et donnons à ses attributs des valeurs :

shell
var car = new Car();
car.brand = "Alfa Romeo";
car.model = "159 SW";
car.firstRegistrationYear = 2007;
car.horsePower = 200;
car.width = 1828;
car.length = 4660;

On peut aussi définir un constructeur, qui nous permettra de créer l'objet plus rapidement :

shell
class Car {
  brand: string;
  model: string;
  firstRegistrationYear: number;
  horsePower: number;
  width: number;
  length: number;

  constructor(brand: string, model: string, firstRegistrationYear: number, horsePower: number, width: number, length: number) {
    this.brand = brand;
    this.model = model;
    this.firstRegistrationYear = firstRegistrationYear;
    this.horsePower = horsePower;
    this.width = width;
    this.length = length;
  }

  drive() {
    console.log("I'm driving my " + this.brand + " " + this.model + " from " + this.firstRegistrationYear);
  }
}

var car = new Car("Alfa Romeo", "159 SW", 2007, 200, 1828, 4660);

On peut ensuite appeler la méthode drive comme ceci :

shell
var car = new Car("Alfa Romeo", "159 SW", 2007, 200, 1828, 4660);
car.drive();

I'm driving my Alfa Romeo 159 SW from 2007

↗
TypeScript Classes

Explique les classes

typescriptlang.org

L'héritage

En TypeScript, une classe peut hériter d'une autre, c'est-à-dire qu'elle inclut tous les attributs et les méthodes de cette dernière. Prenons exemple deux classes : Pickup et FormulaOne. Ces deux classes vont logiquement partager des choses en commun, étant donné que ce sont tous les deux des voitures. Pour éviter de déclarer en double des attributs ou des méthodes, on peut dire que ces classes vont hériter de Car, donc récupérer tous ses attributs et méthodes, et si besoin rajouter des attributs et méthodes :

shell
class Pickup extends Car {
  loadCapacity: number;

  constructor(brand: string, model: string, firstRegistrationYear: number, horsePower: number, width: number, length: number, loadCapacity: number) {
    super(brand, model, firstRegistrationYear, horsePower, width, length);
    this.loadCapacity = loadCapacity;
  }

  start() {
    console.log("TataTataTataTataTataTata! TataTataTataTataTataTataRrrrrrRRRrrrrrRRrrRRRrrrrRRRrr");
  }
}

class FormulaOne extends Car {
  maxSpeed: number;

  constructor(brand: string, model: string, firstRegistrationYear: number, horsePower: number, width: number, length: number, maxSpeed: number) {
    super(brand, model, firstRegistrationYear, horsePower, width, length);
    this.maxSpeed = maxSpeed;
  }

  goVeryFast() {
    console.log("Nnnniiiiiiiiiiiioooonnnnnnnnnnnnnnnnnnn");
  }
}

var pickup = new Pickup("Ford", "Ranger", 2016, 160, 1860, 5362, 455);
var formulaOne = new FormulaOne("Ferrari", "F1", 2017, 1000, 1800, 4500, 320);

pickup.drive();
pickup.start();

formulaOne.drive();
formulaOne.goVeryFast();

shell
I'm driving my Ford Ranger from 2016
TataTataTataTataTataTata! TataTataTataTataTataTataRrrrrrRRRrrrrrRRrrRRRrrrrRRRrr
I'm driving my Ferrari F1 from 2017
Nnnniiiiiiiiiiiioooonnnnnnnnnnnnnnnnnnn

La méthode super appelle le constructeur parent, ce qui évite de recoder le constructeur en entier. Comme tu peux le voir, les objets pickup et formulaOne peuvent tous les deux appeler la méthode drive, car leurs types étendent tous le deux le type Car, qui contient la méthode drive.

↗
TypeScript Classes

Explique les classes et l'héritage

typescriptlang.org

Challenge

L'arche de Noé en TypeScript

Voici une liste d'animaux et d'actions possibles sur ceux-ci :

Animaux :

  • Chat européen (noir)
  • Chat chartreux
  • Chien Terre-Neuve (noir)
  • Chien Moon Moon
  • Mésange
  • Merle (noir)
  • Thon
  • Requin
  • Asticot

Et les actions possibles:

  • On peut photographier tous les animaux
  • Tous les chats peuvent miauler
  • Tous les chiens peuvent aboyer
  • Tous les oiseaux peuvent voler
  • Tous les poissons peuvent nager
  • On peut caresser tous les animaux à 4 pattes
  • On peut nourrir tous les animaux de couleur noire

Tu dois créer 7 fonctions (correspondants aux 7 actions), prenant chacune le bon type de paramètre. Tu dois donc créer au-dessus de ces 7 fonctions les types correspondants ! Par exemple, si les actions étaient de pouvoir regarder avec une loupe tous les insectes, et de pouvoir écraser les moustiques (les pauvres...), il faudrait créer ceci :

shell
class Insecte {

}

class Moustique extends Insecte {

}

function regarderAvecUneLoupe(insecte: Insecte) {
  console.log("Quel joli insecte !");
}

function ecraser(moustique: Moustique) {
  console.log("Zut il est collé sur ma main maintenant...");
}

Attention, les 5 premières actions sont assez faciles, mais les deux dernières ont besoin d'une petite réflexion supplémentaire, avec l'usage des interfaces

Tu dois mettre ton code dans un fichier noe.ts, le mettre sur un Gist et mettre le lien de ce gist comme solution.

PS : Aucun insecte n'a été maltraité durant la réalisation de cette quête.

Critères de validation

  • Les interfaces sont utilisées
  • Les classes sont utilisées
  • L'héritage est utilisé
  • Il y a bien 7 fonctions
  • Les fonctions ne doivent avoir qu'un seul paramètre
  • Les fonctions prennent en paramètre les bons animaux