Par Valentin Brosseau / @c4software
Pourquoi la Programmation Orientée Objet ?
En groupe de 2 ou 3
Concept de modélisation à travers la notion de classe et d’instanciation de ces classes.
Concept d’action à travers la notion d’envoi de messages et de méthodes à l’intérieur des objets.
Concept de construction en créant un objet en reposant sur la définition d’une classe.
Concept d'encapsulation l'accès aux propriétés se fait via un getter et un setter (inaccessible de l'exterieur de l'objet).
Ça permet de représenter informatiquement quelque chose du monde réel.
Représente une définition d'une problématique réelle.
Serviront de moule pour créer des objets.
Une classe étant une définition, elle nous servira plus tard à créer des objets.
class Personne
{
// Attribut
private $nom;
private $prenom;
private $dateNaissance;
private $salaire;
public $nbEnfant;
// Constructeur
function __construct($nom, $prenom, $dateNaissance, $nbEnfant = 0)
{
$this->nom = $nom;
$this->prenom = $prenom;
$this->dateNaissance = $dateNaissance;
$this->nbEnfant = $nbEnfant;
}
// Mutateurs
public function setSalaire($valeur)
{
$this->salaire = $valeur;
}
// Accesseur
public function getSalaire($valeur)
{
return $this->salaire;
}
// Méthode
public function identite(){
return $this->nom . " " . $this->prenom;
}
// Méthode
public function age()
{
$date = new DateTime($this->dateNaissance);
$now = new DateTime();
$interval = $now->diff($date);
return $interval->y;
}
// Méthode
public function argentPoche()
{
return $this->salaire / $this->nbEnfant;
}
}
<?php
class SimpleClass
{
// déclaration d'une propriété
public $var = 'une valeur par défaut';
public $var2 = 'une valeur par défaut';
// Constructeur
function __construct($var, $var2)
{
$this->var = $var;
$this->var2 = $var2;
}
// déclaration des méthodes
public function displayVar() {
echo $this->var;
}
public function setVar($var){
$this->var = $var;
}
public function setVar($var, $var2){
$this->var = $var;
$this->var2 = $var2;
}
}
?>
Chaque objet représente un objet du monde réel
exemple :
⚠️ Utilise les classes précédemment définies ⚠️
$personne1 = new Personne("Valentin", "Brosseau", "28/02/1987", 0);
$personne2 = new Personne("John", "Doe", "01/01/1970", 12);
👀 Créer un objet == Instancier 👀
Nous souhaitons modéliser la problématique d'un vendeur de voitures.
Supposons que chaque Voiture possède :
Une solution possible
« La relation » entre deux classes.
Une personne possède une ou des voiture(s).
class Voiture {
private Integer $vitesse;
private Integer $nombreKm;
private Date $annéeFabrication;
private Personne $lePropriétaire;
// Reste de la classe
function affecterPropriétaire($propriétaire){
$this->lePropriétaire = $propriétaire
}
}
Aide mémoire écriture
$personne1 = new Personne("Valentin", "Brosseau", "28/02/1987", 0);
$personne2 = new Personne("John", "Doe", "01/01/1970", 12);
Regrouper plusieurs objets « dans une liste »
Exemple, comment gérer le cas de :
« Une entreprise contient des personnes (employés) »
Définition : Une collection est un ensemble d'objets qui sont regroupés ensemble sous un même nom.
PHP
$lesPersonnes = [];
$unePersonne = new Personne("Doe", "John", "01/01/1970", 10);
array_push($lesPersonnes, new Personne("Brosseau", "Valentin", "28/02/1987", 0));
array_push($lesPersonnes, $unePersonne);
$lesPersonnes = [];
sizeof($lesPersonnes);
Un parallèle intéressant.
PHP
Java
En PHP :
foreach($lesPersonne as $laPersonne){
// $laPersonne contient « un pointeur » vers une des personne de la liste
// À chaque tour de boucle nous avons la personne suivante.
}
En Java :
// Version moderne
lesPersonnes.forEach(laPersonne -> {
// laPersonne contient « un pointeur » vers une des personne de la liste
// À chaque tour de boucle nous avons la personne suivante.
});
// Version « à l'ancienne »
for (Personne laPersonne : lesPersonnes) {
// laPersonne contient « un pointeur » vers une des personne de la liste
// À chaque tour de boucle nous avons la personne suivante.
}
Aide mémoire écriture et comparaison
L'héritage
Ça vous évoque quoi ?
L’héritage permet :
class Mammifere { protected $vertebre = true; protected $espece = ""; public __construct($espece) { this->$espece = $espece; } public print() { echo "Je suis un mammifère"; } public function manger(){ return ""; } } class Humain extends Mammifere { private $prenom = ""; function __construct($prenom) { parent::__construct("Humain"); this->$prenom = $prenom; } public function manger(){ return "Je suis omnivore"; } } $unHumain = new Humain("Valentin"); $unHumain->print(); // Je suis un mammifère. $unHumain->manger(); // Je suis omnivore.
class Mammifere { protected $vertebre = true; protected $espece = ""; public __construct($espece) { this->$espece = $espece; } public print() { echo "Je suis un mammifère"; } public function manger(){ return ""; } } class Humain extends Mammifere { private $prenom = ""; function __construct($prenom) { parent::__construct("Humain"); this->$prenom = $prenom; } public function manger(){ return "Je suis omnivore"; } } $unHumain = new Humain("Valentin"); $unHumain->print(); // Je suis un mammifère. $unHumain->manger(); // Je suis omnivore.
class Mammifere { protected $vertebre = true; protected $espece = ""; public __construct($espece) { this->$espece = $espece; } public print() { echo "Je suis un mammifère"; } public function manger(){ return ""; } } class Humain extends Mammifere { private $prenom = ""; function __construct($prenom) { parent::__construct("Humain"); this->$prenom = $prenom; } public function manger(){ return "Je suis omnivore"; } } $unHumain = new Humain("Valentin"); $unHumain->print(); // Je suis un mammifère. $unHumain->manger(); // Je suis omnivore.
Comment détecter l'héritage ?
class Chien extends Mammifere
class Chat extends Mammifere
class Humain extends Mammifere
class Etudiant extends Personne {
// … Reste de la classe…
public function formater(){
if($this->estMajeur()){
return "L'étudiant est majeur";
} else {
return "L'étudiant n'est pas majeur";
}
}
}
Que constatez-vous ?
Deux solutions :
$this->estMajeur(); // Appel la méthode la plus proche.
parent::estMajeur(); // Appel la méthode de la classe parente.
Car les enfants peuvent redéfinir les méthodes de la classe parente. (Redéfinition / Override)
class Personne {
protected int age = 0;
public function estMajeur(){
return $this.age >= 18;
}
}
class Americain extends Personne {
/**
* @override
* @return bool
* @description Retourne vrai si la personne est majeur.
*/
public function estMajeur(){
return $this->age >= 21;
}
}
En cas de redéfinition, on parle de spécialisation. C'est-à-dire que l'enfant sera plus précis que le parent.
Un autre exemple du monde réel ?
class Mammifere {
protected $espece = "";
public __construct($espece) {
$this->espece = $espece;
}
/**
* Affiche l'espèce
*/
public function print() {
echo "Je suis un $this->espece";
}
}
class Humain extends Mammifere {
private $prenom = "";
function __construct($prenom)
{
parent::__construct("Humain");
$this->prenom = $prenom;
}
/**
* Affiche l'espèce & le prénom
*/
public function print(){
parent::print();
echo "Je m'appelle $this->prenom";
}
}
class Chien extends Mammifere {
private $nom = "";
function __construct($nom)
{
parent::__construct("Chien");
$this->nom = $nom;
}
}
Mise en pratique.
class Greeting {
public static function welcome() {
echo "Hello World!";
}
}
Greeting::welcome();
Classe dont l'implémentation n'est pas complète et qui n'est pas instanciable.
Non instanciable ? Qu-est-ce que ça veux dire ?
new MaClassAbstraite()
Encapsulation ? Pouvez-vous me redonner la définition.
Avez-vous déjà vu des classes asbtraites ?
abstract class EtudiantAbstrait
{
// Force les classes filles à définir cette méthode
abstract protected function getSpecificite();
abstract protected function setSpecificite($valeur);
// méthode commune
public function parler() {
print "Je suis " . $this->getSpecificite() . "\n";
}
}
class EtudiantSIO extends AbstractClass
{
$option = "";
function __construct($option){
$this->option = $option;
}
protected function getSpecificite() {
return $this->option;
}
protected function setSpecificite($valeur) {
$this->option = $valeur
}
}
Une interface ressemble à une classe abstraite dans laquelle aucune méthode ne serait implémentée.
Classes abstraites et interfaces ont chacune une fonction bien distincte :